app: poll
kernel: sys_poll
do_sys_poll(.....,timeout_jiffies)
poll_initwait(&table);
init_poll_funcptr(&pwd->pt,_pollwait); > table -> qproc = _pollwait
do_poll(nfds, head, &table, timeout)
for (; ; )
{
if (do_pollfd(pfd, pt)) { >mask = file -> f_op -> poll(file, pwait); return mask;
//把当前进程挂到休眠队列里面
count++; //如果驱动的返回值非0,则count++
pt = NULL;
}
if (count || !*timeout || signal_pending(cuttent)) //有信号等待处理
break;
_timeout = schedule_timeout(_timeout) //如果没有事情发生,则*timeout减为0
}
程序分析:
中断执行:
ev_press = 1; /* 表示中断发生了 */
wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */
static unsigned forth_drv_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait); // 不会立即休眠
if (ev_press) //当有按键按下时,mask就不等于0,则上面的跳出for
<span style="white-space:pre"> </span>//没有键按下,则mask=0,》count为0,然后会进入休眠_timeout = schedule_timeout(_timeout)
mask |= POLLIN | POLLRDNORM;
return mask;
}
while (1)
{
ret = poll(fds, 1, 5000); //在一定的时间内,没有按键发生,会休眠
if (ret == 0)
{
printf("time out\n");
}
else
{
read(fd, &key_val, 1);
printf("key_val = 0x%x\n", key_val);
}
}
感谢韦老师的讲解