调试了一个下午,后来还是晚上回去查看了以前写的代码才调试好,其实很简单,就是差一点点了。不知到错在哪里。
本来是很简单的,要实现一个poll轮询,定义了file_operations的poll实现函数:
static unsigned int eventpoll(struct file *file, poll_table *wait) { unsigned int mask = 0; poll_wait(file, &uart_wait, wait); printk("sclu have poll data\n"); if(value > 0) { mask |= POLLIN | POLLRDNORM; value = 0; } return mask; }
这才是正确的,可是先前就是没有判断value>0的条件,弄得结果是,上层每次轮询都有结果返回,不断循环。
poll_wait只是把uart_wait注册到了等待队列上,然后返回;这是执行了一次eventpoll函数,这时候还没有休眠,休眠的时刻是eventpoll函数返回后,即调用eventpoll函数的地方,在文件系统的do_sys_poll函数中,用schedule_timeout让进程进入休眠;
以后就会进入休眠;
直到定时的时间到了,或者驱动中wake_up_interruptible唤醒对应的uart_wait;如果是前者,则直接返回用户空间;如果是后者,它醒来后再次进入eventpoll函数,看到value不为0,返回POLLIN的结果;或许你会问,第二次进来的时候不是又调用了一次poll_wait吗?是的,但是第二次调用返回到do_sys_poll函数时候,由于得到结果(POLLIN)了,所以要退出do_sys_poll函数了,这时候会调用poll_freewait(&table)释放掉资源,把结果返回用户空间;
所以从poll开始到有数据到来wake up,一共执行两次eventpoll函数;如果是timeout,则只执行一次eventpoll函数。
可见,驱动中poll_wait的作用只是为了能让wake_up_interruptible能找到要唤醒的进程。没有poll_wait,进程到timeout后也一样能被唤醒;当然,如果用户空间设置time的时间为-1(即无限长),则不会被唤醒了。
还有read函数也出错啊:
static ssize_t gzsd_input_read(struct file *filp, char __user *buffer,int size, loff_t *ppos) { char buf[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; buf[0] = value; printk("sclu %s\n", __FUNCTION__); if (copy_to_user(buffer, buf, sizeof(buf))) { printk("copy data to user err\n"); } return sizeof(buf); }