此爲部分內核代碼。
應用程序的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;
*}
}