驱动实现异步通知

 

在应用层中,通过异步通知的机制来处理随时发生的事件。例如用signal来俘获信号

void handler(){
 .
 .
}

int main(){
 .
 .
 signal(SIGINT,handler);
}

如果想让设备文件拥有异步通知机制,那么,在主函数中是这样实现的
int main(){
 int flag;
 int fd=open("/dev/hello",O_RDWR);
 .
 signal(SIGIO,handler);
 fcntl(fd,F_SETOWN,getpid());  //原型int fcntl(int fd , int cmd,.);3个或2个参数。这个函数的意思是
                 使fd干嘛。这里是使fd的拥有者是当前进程。
 flag=fcntl(fd,F_GETFL);      //获得fd的状态,
 fcntl(fd,F_SETFL,flag|FASYNC);//使fd的状态在原来上加上异步状态。
  .
  .
}
完成了这些,在内核相对应的file结构体就会被设置成上面的样子,也就是拥有了FASYNC状态。

在驱动层,要完成的事情就是实现对F_SETOWN和F_SETFL的支持。而F_SETOWN在内核已经帮我们实现了,我们的工作
就是F_SETFL的支持了,很简单,只要完成operations结构体中的fasync方法即可。

fasync的参数是这样的
static int my_fasync(int fd, struct file * filp, int on)
第一个是要异步通知的文件描述符,第二个是file结构,目的是要他的filp->private_data,第三个是模式位,当应用层
把file设成FASYNC状态是,on会被指1,然后传给系统函数fasync_helper,在内核中的fasync_helper的原型如下

int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
{
    if (!on)
                return fasync_remove_entry(filp, fapp);
        return fasync_add_entry(fd, filp, fapp);
}

也就是会把设备登记到队列中。
那么 operations的fasync可以这样写
int my_fasync(int fd, struct file * filp, int on){
    struct dev *dev=filp->private_data;
    return fasync_helper(fd, filp, mode, &dev->async_queue);
}

相应的,在close后,也就是驱动的release函数中,要调用my_fasync函数,传递的参数是
-1,filp,0 也就是传递0给内核,让他remove掉队列。 fd传递-1是表示本设备对应的所有的进程所打开的
文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值