上一节实现了中断方式的按键驱动,但是在测试程序中还是一个while循环,不断的read,read()函数会一直等待按键按下,不会返回. 这节我们实现如果5s 没有按键按下则返回,这就要用到poll机制。
poll 机制可以实现休眠,当有按键按下时立即返回;若一直没有按键按下,时间到了,也返回。
下面我们为keys_drv 驱动添加 poll 机制:
1. 在 file_operations 中添加 poll ,这样 在应用程序中调用poll()时,就会调用驱动中的poll.
3. 相应的测试程序: keys_test.c
在应用程序中调用 poll 和 select 是一样的,最终都会调用到驱动中的poll().
poll 机制可以实现休眠,当有按键按下时立即返回;若一直没有按键按下,时间到了,也返回。
下面我们为keys_drv 驱动添加 poll 机制:
1. 在 file_operations 中添加 poll ,这样 在应用程序中调用poll()时,就会调用驱动中的poll.
static struct file_operations sencod_drv_fops = {
.owner = THIS_MODULE,
.open = forth_drv_open,
.read = forth_drv_read,
.release = forth_drv_close,
.poll = forth_drv_poll,
};
2. 在驱动代码中 添加 poll()函数,看一下这个poll() 函数 怎么写:
#include <linux/poll.h>
static unsigned forth_drv_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
/* 把这个进行挂到等待队列中去,但不会立即休眠
等运行到 shedule_timeout()时才会休眠
*/
poll_wait(file, &button_waitq, wait);
if (ev_press)
mask |= POLLIN | POLLRDNORM;
return mask;
}
关于 poll 的调用流程关系如下所示:
3. 相应的测试程序: keys_test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
int main(int argc, char **argv)
{
int fd;
unsigned char key_val;
int ret;
struct pollfd fds[1]; //poll 可以同时查询多个文件,这里只查询一个
fd = open("/dev/buttons", O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
fds[0].fd = fd;
fds[0].events = POLLIN;
while (1)
{
ret = poll(fds, 1, 5000); //5秒超时
if (ret == 0)
{
printf("time out\n");
}
else
{
read(fd, &key_val, 1);
printf("key_val = 0x%x\n", key_val);
}
}
return 0;
}
这样 在指定时间内如果没有按键按下,则 poll()方法返回,但并没有退出while循环。
在应用程序中调用 poll 和 select 是一样的,最终都会调用到驱动中的poll().