Linux设备驱动之poll机制

       应用程序调用的任何库函数,最终将会调被库函数封装的系统函数 ,此过程中发生swi中断,用户进程从用户状态变成了核心态,当我们的应用程序调用pool() 函数时,最终调用的是 sys_poll() 函数。

       sys_poll()的函数原型如下:

       asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,long timeout_msecs)。

       解读:函数定义前加宏asmlinkage ,表示这些函数通过堆栈而不是通过寄存器传递参数。 gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器。缺省时采用寄存器,假如你要在你的汇编过程中调用c语言函数,并且想通过堆栈传递参数,你定义的c函数时要在函数前加上宏asmlinkage。对于函数的相关参数类型,可以在主机系统中通过 man poll 命令,查看相关参数的介绍,这里就不列举出来。

       Pool机制相关函数的调用流程:

(1)pool()函数调用sys_poll()函数。sys_poll()函数首先处理传入的超时时间的值,接着调用do_sys_poll(ufds, nfds, &timeout_jiffies) 函数。

(2)do_sys_poll()函数调用poll_initwait(&table) 来初始化进程等待表,接着调用do_poll(nfds, head, &table, timeout)函数。

(3)do_poll(nfds, head, &table, timeout)函数调用do_pollfd()函数,do_pollfd()函数调用设备驱动程序中自己写的 XXX_poll() 函数,如果XXX_poll()函数返回1,则count加1。

    Select.c文件中do_poll() 函数的部分关键代码:

    for (walk = list; walk != NULL; walk = walk->next) {

                     struct pollfd * pfd, * pfd_end;

                     pfd = walk->entries;

                     pfd_end = pfd + walk->len;

                     for (; pfd != pfd_end; pfd++) {

                            if (do_pollfd(pfd, pt)) {

                                   count++;

                                   pt = NULL;

                            }

                       }

               }

      双层for循环,可以检查多个设备,

     接下来,do_poll()  函数会判断函数到底是直接返回 还是先使进程进入休眠,等待你传入的timeout_msecs 时间后再恢复运行

      if (count || !*timeout || signal_pending(current))

              break;

     从上面可以看到,直接返回的条件:有设备(count不等于0),超时,等待信号。同时poll() 函数返回值为设备数的值。

     否则的话,程序继续执行。

     最终执行到:

              __timeout = schedule_timeout(__timeout),进程进入休眠。

      休眠指定的时间之后:

              __set_current_state(TASK_RUNNING),进程又恢复运行,poll() 函数返回值为0

       在驱动程序中,自己的xxx_poll() 函数一定要调用poll_wait() 函数,把进程送入等待表中,不然某一事件(中断)使进程就绪后,找不到去哪唤醒,不能及时反应。可能使得响应动作延迟到休眠主动结束 才发生。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值