linux设备驱动之异步通知

一.对异步通知的介绍          

          首先明确异步通知的概念:当设备准备就绪时,主动的去通知应用程序。这样应用程序就可以不用一直的查询设备的状态,便可以节省很多资源。比较准确的可以称为“信号驱动的异步I/O”。

            这里说的信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。

           异步通知意味着设备通知用户自身可以被访问,之后用户再通过程序对设备进行IO处理。

          异步通知图例:展现用户空间和内核空间之间的关系

         

二.linux异步通知编程

1.linux信号

          异步通知使用信号来实现。在linux中有30种信号来被使用。特殊的信号:SIGSTOP和SIGKILL两个信号进程不能捕获和忽略,其余的信号都可以。

信号捕获的意思是指当一个信号到达时有相应的代码处理它。如果一个信号没有被进程所捕获,内核将采用默认的行为来处理。

2.信号的接收 

        信号的接收是由应用层来接收。在用户程序中,为了捕获信号,可以使用signal()函数来设置对应信号的处理函数:

        void(*signal(int signum,void(*handler))(int)))(int);

       可以分解为:typedef void (*sighandler_t)(int);

                               sighandler_t signal(int signum,sighandler_t handler);

       第一个参数指的是信号的值,第二个参数是针对前面信号的值的处理函数 ,在这里当为SIG_IGN时表示忽略该信号,SIG_DFL时表示采用系统默认方式处理信号,若用户自定义处理函数则当信号到达时被调用。

     信号也可以用sigaction()函数来设置。它可用于改变进程接收到特定信号的行为。函数原型:

     int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);

     函数第一个参数为信号的值,第二个参数是指向结构体sigaction的一个实例的指针,在sigaction的实例中指定了对特定信号的处理函数,若为空将以缺省的方式对信号进行处理。第三个参数oldact指向的对象用来保存原来对相应信号的处理函数,可指定为NULL。当第二个和第三个参数都为NULL时,可以用来检查信号的有效性。

     启动信号的机制(应用程序中):

    例:、

    int oflags;

    signal(SIGIO,button_handler);     //告诉是什么信号,并设置信号处理函数

    fcntl(fd,F_SETNOWN,getpid());   //告诉内核用户程序的进程号,也就是明确内核要将信号发给哪个进程

   oflags=fcntl(fd,F_GETFL);           

   fcntl(fd,F_SETFL,oflags | FASYNC);   //启用异步通知机制,对设备设置FASYNC标志。

   应用程序从内核接收信号的总结:

   1..F_SETNOWN  使设备驱动发出的信号只能被本进程接收到

   2.F_SETFL 使设备文件支持FASYNC,即异步通知模式

   3.signal()函数连接信号和信号处理函数。

3.信号的释放

    仅有应用端信号的接收是不够的,信号的源头在设备端,所以要在驱动程序中添加相应的释放信号的代码。

   1.支持F_SETNOWN 命令,这个是由内核完成的,驱动程序无需处理

   2.支持F_SETFL命令,当FASYNC标志改变时,驱动程序中的fasync()函数将执行,所以驱动程序中应该实现fasync()函数。这个函数进行初始化。

   3调用kill_fasync()函数激发相应的信号。

处理FASYNC标志变更的函数

int fasync_helper(int fd,struct file *filp,int mode,struct fasync_struct **fa);

释放信号的函数

void kill_fasync(struct fasync_struct **fa,int sig,int band);

在最后的文件关闭时,应将文件从异步通知的列表中删除。

*************************************************************************************************************************************************************************************

对异步通知的总结:

     1.应用程序           注册信号处理函数

     2.谁发                  驱动程序发

     3.怎么发              kill_fasync()也需要一个fasync()函数 当应用程序执行时,驱动程序先执行这个fasync()函数

     4.发给谁              信号发给应用程序,而且应用程序需要告诉内核程序进程号

**************************************************************************************************************************************************************************************

***本文中用户程序和应用程序指的是同一个

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值