1.poll机制
在上一节的程序中,用的是阻塞的方式,即当有按键按下时,中断服务程序唤醒read进程,然后read函数继续执行,否则就永远休眠下去,这个固然OK,但是有时候需要用到一个节点,当超过这个时间是,节输出错误信息或则是不等待了,继续执行执行其他程序去
2.对sys_poll( )函数的分析
asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
long timeout_msecs)
{
s64 timeout_jiffies;
if (timeout_msecs > 0) {
#if HZ > 1000
/* We can only overflow if HZ > 1000 */
if (timeout_msecs / 1000 > (s64)0x7fffffffffffffffULL / (s64)HZ)
timeout_jiffies = -1;
else
#endif
timeout_jiffies = msecs_to_jiffies(timeout_msecs);
} else {
/* Infinite (< 0) or no (0) timeout */
timeout_jiffies = timeout_msecs;
}
return do_sys_poll(ufds, nfds, &timeout_jiffies);
}
应用程序调用poll函数,进入内核后会调用sys_poll( )函数,会挂载当前进程到队列里去。sys_poll( )函数会调用do_sys_poll( )函数
int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
3.在驱动程序中写的poll函数
int fourth_drv_poll(struct file *file, poll_table_struct *wait)
{
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait); /* 将进程挂接到button_waitq等待队列下 */
/* 根据实际情况,标记事件类型 */
if (ev_press)
mask |= POLLIN | POLLRDNORM;
/* 如果mask为0,那么证明没有请求事件发生;如果非零说明有时间发生 */
return mask;
}
定义:
poll函数:
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
fds :可以传递多个结构体,也就是说可以监测多个驱动设备所产生的事件,只要有一个产生了请求事件,就能立即返回
struct pollfd {
int fd; /* 文件描述符 */
short events; /* 请求的事件类型,监视驱动文件的事件掩码 */
short revents; /* 驱动文件实际返回的事件 */
};
nfds:监测驱动文件的个数
timeout:超时时间,单位为ms
参数events可以有下列值:
POLLIN 有数据可读
POLLRDNORM 有普通数据可读,等效与POLLIN
POLLPRI 有紧迫数据可读
POLLOUT 写数据不会导致阻塞
POLLER 指定的文件描述符发生错误
POLLHUP 指定的文件描述符挂起事件
POLLNVAL 无效的请求,打不开指定的文件描述符
poll函数的返回值:
有事件发生 返回revents域不为0的文件描述符个数(也就是说事件发生,或者错误报告)
超时 返回0;
失败 返回-1,并设置errno为错误类型