轮询
应用程序中使用的系统调用select()和poll()查询是否可对设备驱动进行无阻塞的访问,他们都是最终引发驱动
中的poll()函数被执行。
应用程序中的轮询
#include <sys/select.h>
int select( int nfds, fd_set FAR* readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout);
该函数用于监视一个或者多个文件描述符的变化情况——读写或是异常,发生变化后我们就可以去做相应处理read
或者write()。
驱动程序中的轮询
设备驱动中poll()的原型
unsigned int (*poll) (struct file *, struct poll_table_struct *);该函数进行两项工作
1,对可能引起设备文件状态变化的等待队列调整用poll_wait()函数,将对应的等待队列头添加到poll_table。
2,返回表示是否能对设备进行无阻塞读,写访问的掩码。
关键的用于向poll_table注册等待队列的poll_wait()函数的原型如下:
void poll_wait(struct file *filp, wait_queue_head_t *queue, poll_table * wait);它所有的工作是把当前进程添加到wait
参数指定的等待列表(poll_table)中。驱动程序中poll()应该返回设备资源的可获取状态,即POLLIN,POLLOUT,
POLLPRI,POLLERR,POLLNVAL等宏的位“或”结果。每个宏的含义都表明设备的一种状态,如POLLIN(定义为0x0001)
意味着设备可以无阻塞地读,pollout(定义为0x0004)意味着设备可以无阻塞的写。
static unsigned int xxx_poll(struct file *filp, struct poll_table_struct * wait)
{
unsigned int mask = 0;
struct xxx_dev *dev = filp->private_data; /*获取设备结构体指针*/
...
poll_wait(filp, &dev->r_wait, wait); /*加读等待队列头*/
poll_wait(filp, &dev-w_r_wait, wait); /*加写等待队列头*/
if(...) /*可读*/
mask |= POLLIN | POLLRDNORM; /*标示数据可获得*/
if(...) /*可写*/
mask |= POLLOUT | POLLWRNORM; /*标示数据可写入*/
...
return mask;
}