前言
本文基于S3C2440开发板。
一、poll机制分析
所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应
的函数。比如系统调用 open、read、write、poll,与之对应的内核函数为:sys_open、sys_read、sys_write、sys_poll
。对于系统调用 poll 或 select,它们对应的内核函数都是sys_poll
。分析sys_poll
,即可理解 poll机制。
二、用户程序到驱动程序的过程分析
- poll > sys_poll > do_sys_poll > poll_initwait,poll_initwait 函数注册一下回调函数__pollwait,
它就是我们的驱动程序执行 poll_wait 时,真正被调用的函数。 - 接下来执行 file->f_op->poll,即我们驱动程序里自己实现的 poll 函数
它会调用 poll_wait 把自己挂入某个队列,这个队列也是我们的驱动自己定义的;
它还判断一下设备是否就绪。 - 如果设备未就绪,do_sys_poll 里会让进程休眠一定时间
- 进程被唤醒的条件有 2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程
序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过 poll_wait
把本进程挂过去的队列。 - 如果驱动程序没有去唤醒进程,那么 chedule_timeout(__timeou)超时后,会重复 2、3 动
作,直到应用程序的 poll 调用传入的时间到达。
三、中断和poll的结合
①这里的do_pollfd实际上就是我们驱动程序的poll,当我们驱动程序的poll返回值不为0时,count会++,也就是下面的判断条件会成立,会跳出这个循环,不执行休眠进程。如果返回值为0,只能等待到时间timeout==0,才能跳出循环,不休眠进程。
②可以在我们的驱动程序poll中加条件判断是否发生中断,发生中断poll函数就返回不为0的值。
static unsigned s3c2440_button_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait); // 不会立即休眠
/*这里是用于中断发生,在poll机制中,返回一个不为0的值,结束死循环,不执行休眠进程
*poll轮询机制,正常是时间到了才跳出一个死循环唤醒进程 */
if (ev_press) //按键按下中断的标志位
mask |= POLLIN | POLLRDNORM;
return mask;
}