linux异步通知

本文详细介绍了Linux系统中异步通知机制的实现原理及其在驱动程序与用户空间间通信的应用。通过具体的代码示例,展示了如何在驱动层通过fasync_helper和kill_fasync函数以及在应用层利用SIGIO信号来实现异步通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux 异步通知


要弄明白这个问题,我们得从最基本的原理开始。我们知道,驱动程序运行在内核 空间中,应用程序运行
在用户空间中,两者是不能直接通信的。但在实际应用中,在设备已经准备好的时 候,我们希望通知用户
程序设备已经ok,用户程序可以读取了,这样应用程序就不需要一直查询该设备 的状态,从而节约了资源
,这就是异步通知。
好,那下一个问题就来了,这个过程如何实现呢?简单,两方面的工作。




一 驱动方面:
1. 在设备抽象的数据结构中增加一个struct fasync_struct的指针
2. 实现设备操作中的fasync函数,这个函数很简单,其主体就是调用内核的fasync_helper函数。
3. 在需要向用户空间通知的地方(例如中断中)调用内核的kill_fasync函数。
呵呵,简单吧,就三点。其中fasync_helper和kill_fasync都是内核函数,我们只需要调用就可以了。在

1中定义的指针是一个重要参数,fasync_helper和 kill_fasync会使用这个参数。

二 应用层方面
1. 利用signal的SIGIO信号的处理函数my_signal_fun
2. fcntl的F_SETOWN指令设置当前进程为设备文件owner
3. fcntl的F_SETFL指令设置FASYNC标志
完成了以上的工作的话,当内核执行到kill_fasync函数,用户空间SIGIO函数的处理函数就会被调用了。
呵呵,看起来不是很复杂把,让我们结合具体代码看看就更明白了。


驱动层:

中断处理函数

{

.........

kill_fasync (&button_async, SIGIO, POLL_IN);

.........

}



int fifth_drv_fasync(int fd, struct file *filp, int on)
{
printk("fifth_drv_fasync\n");


fasync_helper(fd, filp, on, &button_async); //初始化button_async结构体
return 0;


}


static struct file_operations fifth_drv_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   fifth_drv_open,     
.read = fifth_drv_read,  
.release= fifth_drv_close,
.poll   = fifth_drv_poll,
.fasync =   fifth_drv_fasync,
};


应用层:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>


int fd;




void my_signal_fun(int signum)
{
unsigned char  key_value;


read(fd,&key_value,1);

printf("key_value =0x%0x\n",key_value);

}




int main(int argv, char **argc)
{



int Oflags;
fd = open("/dev/buttons",O_RDWR);
if(fd < 0)
{
printf("can't open device\n");
}



signal(SIGIO,my_signal_fun); //注册信号处理函数


fcntl(fd, F_SETOWN, getpid()); //告诉驱动 app的进程id

Oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, Oflags | FASYNC); //初始化驱动的异步结构体button_async


while(1)
{
sleep(1000);   
}

return 0;

}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值