此为部分内核代码。
应用程序的poll -> sys_poll -> do_sys_poll -> (poll_initwait,和do_poll)
应用程序的部分代码:
int main(int argc,char **argv){
int fd;int val=1;
unsigned char key_val;
int ret;
struct pollfd fds[1];//在poll.h中定义
fd=open("/dev/buttons",O_RDWR);
if(fd<0)
printf("can't open!\n");
fds[0].fd=fd;
fds[0].events = POLLIN; //POLLIN 不阻塞地可读除高优先级外的数据
while(1){
/* int poll (struct pollfd fdarry[ ],nfds_t nfds,int timeout); nfds是数组元素数 ,timeout 等待的毫秒数*/
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);//驱动程序中使用的是十六进制,这里%x输出
}
}
return 0;
}
驱动程序里的poll函数:
static unsigned forth_drv_poll(struct file *file, poll_table *wait)
{
unsigned int mask=0;
poll_wait(file ,&button_waitq,wait); //不会休眠,挂载到队列
if(ev_press) //ev_press =1说明有中断产生,mask返回非零值,
mask |= POLLIN ; //不阻塞地可读除高优先级外的数据
return mask;
}
内核框架:
出现两次函数的,下面的是调用;
do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,struct timespec *end_time)
{
/*
* Structures and helpers for sys_poll/sys_poll
*/
struct poll_wqueues table;
struct poll_wqueues *pwd=&table;
int fdcount;
- poll_initwait(pwq);//初始化;
/*把poll_initwait(pwq)展开
*poll_initwait(pwq)
*{*pwq->polling_task = current;
*pwq->error = 0;
*pwq->table = NULL;
*pwq->inline_index = 0;
* init_poll_funcptr(&pwq->pt, __pollwait);
*init_poll_funcptr(poll_table *pt, __pollwait){
* pt->qproc = __pollwait;
*}
*}
*结果为table.pt.gbroc=_pollwait
* table.error = 0;
* table.table = NULL;
* polling_task = current;
*}
- fdcount = do_poll(nfds, head, &table, end_time);
*do_poll(nfds, head, &table, end_time)
* for (;;) {
* struct poll_list *walk;
* poll_table* pt = &table->pt;
* for (walk = head; walk != NULL; walk = walk->next) {
* struct pollfd * pfd, * pfd_end;
* pfd = walk->entries;
* pfd_end = pfd + walk->len;
* if (do_pollfd(pfd, pt)) {
/*
* 把do_pollfd(pfd, pt)展开,
* mask = file->f_op->poll(file,&table->pt);调用驱动poll函数,
* pfd->revents = mask;
* return mask;
* 把驱动程序的poll函数展开:
* forth_drv_poll(file,&table->pt ){
* poll_wait(file ,&button_waitq,&table->pt);
*}
*把poll_wait(file ,&button_waitq,&table->pt);展开
* &table->ptwait->qproc(file,&button_waitq ,&table->pt);
*由 上面初始化时 : table.pt.gbroc=_pollwait
*相当于_pollwait(file,&button_waitq , &table->pt); //挂载到队列,
*/
count++; //如果驱动程序poll返回非零,count自加
pt = NULL;*}
*}
*}
*}
*if (count || timed_out)*break;
*//不满足,休眠
*if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack))
* timed_out = 1;
*}
}