09-设备驱动中的轮询编程
8.2.3 设备驱动中的轮询编程
设备驱动中poll()函数的原型是:
unsigned int(poll)(struct file filp, struct poll_table* wait);
第1个参数为file结构体指针,第2个参数为轮询表指针。这个函数应该进行两项工作。
(1)对可能引起设备文件状态变化的等待队列调用poll_wait()函数,将对应的等待队列头添加到poll_table。
(2)返回表示是否能对设备进行无阻塞读、写访问的掩码。
关键的用于向poll_table注册等待队列的poll_wait()函数的原型如下:
void poll_wait(struct file filp, wait_queue_heat_t queue, poll_table * wait);
poll_wait()函数的名称非常容易让人产生误会,以为它和wait_event()等一样,会阻塞地等待某事件的发生,其实这个函数并不会引起阻塞。poll_wait()函数所做的工作是把当前进程添加到wait参数指定的等待列表(poll_table)中。
驱动程序poll()函数应该返回设备资源的可获取状态,即POLLIN、POLLOUT、POLLPRI、POLLERR、POLLNVAL等宏的位“或”结果。每个宏的含义都表明设备的一种状态,如POLLIN(定义为0x0001)意味着设备可以无阻塞地读,POLLOUT(定义为0x0004)意味着设备可以无阻塞地写。
通过以上分析,可得出设备驱动中poll()函数的典型模板,如代码清单8.11所示。
代码清单8.11 poll()函数典型模板
1 static unsigned int xxx_poll(struct file filp, poll_table wait)
2 {
3 unsigned int mask = 0;
4 struct xxx_dev dev = filp->private_data; /获得设备结构体指针*/
5
6 ...
7 poll_wait(filp, &dev->r_wait, wait);/ 加读等待队列头 /
8 poll_wait(filp, &dev->w_wait, wait);/ 加写等待队列头 /
9
10 if (...) / 可读 /
11 mask |= POLLIN | POLLRDNORM; /标示数据可获得/
12
13 if (...) / 可写 /
14 mask |= POLLOUT | POLLWRNORM; /标示数据可写入/
15 ...
16 return mask;
17 }