POLL 实现简单举例
内核下面需要做的事情
实现一个字符设备
1、首先实现file_operations 结构 。创建的文件名字为 char_xxx,
static const struct file_operations xxx_fops = {
.owner = THIS_MODULE,
.open = xxx_open,
.release = xxx_release,
.read = xxx_read,
.write = xxx_write,
.mmap = xxx_mmap,
.poll = xxx_poll,
};
我们需要关注的是 xxx_poll 的实现。
2、定义一个等待队列:
static DECLARE_WAIT_QUEUE_HEAD(xxx_waitqueue); //队列
static bool xxx_flg = FALSE; //驱动标记
//poll->do_sys_poll->do_poll->do_follfd,最终会调入我们驱动的poll实现,将当前用户进程加入等待队列里面
static unsigned int xxx_poll(struct file *file, struct poll_table_struct *wait)
{
//将调用poll函数的进程挂在等待xxx_waitqueue队列里面,方便驱动去唤醒这个任务
poll_wait(file, &xxx_waitqueue, wait);
if (xxx_flg ) {
xxx_flg = FALSE;
return POLLIN | POLLRDNORM;
} else {
return 0;
}
}
3、没有中断产生的话,如何唤醒任务
static int xxx_pollwake(coid)
{
xxx_flg = TRUE;
wake_up(&xxx_waitqueue);//创建那个队列的原因是,让驱动有机会去唤醒这个队列的进程
return 0;
}
4、有中断产生,唤醒任务
static int xxx_pollwake(coid)
{
xxx_flg = TRUE;
wake_up_interruptible(&xxx_waitqueue);//创建那个队列的原因是,让驱动有机会去唤醒这个队列的进程,否者只有等到任务等待超时
kill_fasync(&xxx_waitqueue, SIGIO, POLL_IN);
return 0;
}
用户态下面需要做的事情
int user_data_rx (void *data)
{
int fd;
int time_out //任务睡眠超时时间
fd = open(“/dev/char_xxx”, xxx);
poll(fd, xx, time_out); //如果没有poll_wake,将不会往下执行。
........
}