Linux_12th_异步通知

异步通知:

之前的三种读取按键电平状态的方法分别是:查询法、中断法、中断+Poll机制。

这三种方法都需要应用程序主动去读取,我们可以进一步改进,
如果应用程序可以休眠或者做别的事情,当发生按键中断时,驱动中的中断服务函数来主动提醒应用程序去读取就好了。
这个设想可以通过驱动程序给应用程序发信号的方法来实现。
首先明确,目的? 当按键按下时,驱动程序去提醒应用程序读取按键值。(即实现驱动和应用之间的异步通知)
 1.怎么做?    使用信号机制来实现,也就是发信号。
 2.谁发?        驱动程序发信号。
 3.怎么发?    使用kill_fasync
 4.发给谁?    发给应用程序。(应用程序事先要告诉驱动自己的PID)
 5.收到后做什么?  应用程序在信号处理函数中处理要做的工作。
根据以上几点来写出支持异步通知功能的驱动和应用程序。
当中断发生时,进入中断服务函数,将按键值记录下来,然后唤醒进程,并且使用kill_fasync(&buttons_async, SIGIO, POLL_IN)给进程发信号。
第一个参数是一个结构体,buttons_async结构体中显然包含应用程序发给驱动的那个PID;第二个参数表示信号的类别,SIGIO只是一个数字29;
第三个参数表示原因,POLL_IN表示有数据等待读取。
那么在中断发生之前,需要对buttons_async结构体进行初始化。
我们在驱动fasync函数中使用fasync_helper(fd, file, on, &buttons_async)函数来初始化buttons_async结构体。
这就是“谁发”和“怎么发”。
接下来,“发给谁”。
当然是发给应用程序,那应用程序首先得把自己的PID告诉驱动,应用程序通过fcntl这个系统调用把进程ID告诉驱动,fcntl(fd, F_SETOWN, getpid());
Oflags = fcntl(fd, F_GETFL);   
fcntl(fd, F_SETFL, Oflags | FASYNC);  // 改变fasync标记,最终会调用到驱动的faync > fasync_helper:初始化/释放buttons_async结构体
最后,“收到后做什么”
应用程序处于休眠状态,当驱动唤醒进程,并发送信号时,应用程序就会调用信号处理函数,我们需要先调用signal函数来指定我们自己实现的信号处理函数。
signal(SIGIO, my_signal_fun);

在my_signal_fun函数中使用read函数来读取我们在中断服务函数中记录好的按键电平。




  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值