跳转至

07.POLL机制

实验说明

该部分内容基于中断唤醒实验修改,只会有少部分不同。他的原理就是隔一段时间去看一下有没有数据。超时就返回一个超时标志。

修改细节

添加一个POLL函数就可以了。重要的是把当前线程放入队列。

static unsigned int gpio_key_drv_poll(struct file *fp, poll_table * wait)
{
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    poll_wait(fp, &gpio_key_wait, wait);
    return g_key ? (POLLIN | POLLRDNORM) : 0;
}

/* 定义自己的file_operations结构体                                              */
static struct file_operations gpio_key_drv = {
    .owner   = THIS_MODULE,
    .read    = gpio_key_drv_read,
    .poll    = gpio_key_drv_poll,
};

然后实验文件修改如下

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>

/*
 * ./button_test /dev/100ask_button0
 *
 */
int main(int argc, char **argv)
{
    int fd;
    int val;
    struct pollfd fds[1];
    int timeout_ms = 5000;
    int ret;

    /* 1. 判断参数 */
    if (argc != 2) 
    {
        printf("Usage: %s <dev>\n", argv[0]);
        return -1;
    }

    /* 2. 打开文件 */
    fd = open(argv[1], O_RDWR);
    if (fd == -1)
    {
        printf("can not open file %s\n", argv[1]);
        return -1;
    }

    fds[0].fd = fd;
    fds[0].events = POLLIN;


    while (1)
    {
        /* 3. 读文件 */
        ret = poll(fds, 1, timeout_ms);
        if ((ret == 1) && (fds[0].revents & POLLIN))
        {
            read(fd, &val, 4);
            printf("get button : 0x%x\n", val);
        }
        else
        {
            printf("timeout\n");
        }
    }

    close(fd);

    return 0;
}