关闭

Linux_12th_异步通知

标签: linux异步通知
80人阅读 评论(0) 收藏 举报
分类:

异步通知:

之前的三种读取按键电平状态的方法分别是:查询法、中断法、中断+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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12339次
    • 积分:1223
    • 等级:
    • 排名:千里之外
    • 原创:114篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类