zoukankan      html  css  js  c++  java
  • 设备驱动基础学习--poll

    使用非阻塞I/O的应用程序通常会使用select()和poll()系统调用查询是否可对设备进行无阻塞的访问,这两个系统调用最终又会引发设备驱动中的poll()函数被执行,所以我们的问题就集中到了如何编写设备驱动中的poll()函数就可以了。先来看看设备驱动中的poll()函数原型:

    unsigned int (*poll)(struct file *filp, struct poll_table *wait);

    这个函数要进行下面两项工作。首先,对可能引起设备文件状态变化的等待队列调用poll_wait(),将对应的等待队列头添加到poll_table.然后,返回表示是否能对设备进行无阻塞读写访问的掩码。在上面提到了一个poll_wait()函数,它的原型:

    void poll_wait(struct file *filp, wait_queue_head_t *queue, poll_table *wait);

    经过以上驱动程序的poll()函数应该返回设备资源的可获取状态,即POLLIN,POLLOUT,POLLPRI,POLLERR,POLLNVAL等宏的位"或"结果.

    常量说明

    POLLIN普通或优先级带数据可读

    POLLRDNORM普通数据可读

    POLLRDBAND优先级带数据可读

    POLLPRI高优先级数据可读

    POLLOUT普通数据可写

    POLLWRNORM普通数据可写

    POLLWRBAND优先级带数据可写

    POLLERR发生错误

    POLLHUP发生挂起

    POLLNVAL描述字不是一个打开的文件

    基于前面阻塞/非阻塞的文章sample中添加poll函数,并重写app测试程序。

    fellowmisc.c

    #include <linux/poll.h>

    unsigned int fellowmisc_poll(struct file *filep, poll_table *wait)
    {
      unsigned int mask = 0;
      struct fellowmisc_dev *devp = (struct fellowmisc_dev*)filep->private_data;
      poll_wait(filep, &(devp->inq), wait);//将inq加入到poll_table中。
      poll_wait(filep, &(devp->outq), wait);//将outq加入到poll_table中。
      if (devp->free > 0)//有空余空间,可写
      {
        mask |= POLLOUT | POLLWRNORM;
      }
      if (devp->buffer_size - devp->free > 0)//buffer有数据,可读。
      {
        mask |= POLLIN | POLLRDNORM;
      }
      return mask;
    }
    static const struct file_operations fellowmisc_fops ={
    .owner = THIS_MODULE,
    .open = fellowmisc_open,
    .release = fellowmisc_release,
    .unlocked_ioctl = fellowmisc_ioctl,
    .read = fellowmisc_read,
    .write = fellowmisc_write,
    .poll = fellowmisc_poll,
    };

    app.c

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/select.h>
    #include "fellowmisc.h"
    int main(int argc, char **argv)
    {
      int fd = -1;
      int ret = 0;
      fd_set rfds, wfds;
      fd = open("/dev/fellowmisc", O_RDWR);
      if (fd < 0)
      {
        printf("open fail:%s ", strerror(errno));
        return -1;
      }
      while (1)
      {
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        FD_SET(fd, &rfds);
        FD_SET(fd, &wfds);
        select(fd + 1, &rfds, &wfds, NULL, 0);
        if (FD_ISSET(fd, &rfds))
        {
          printf("Device can be read now ");
          char readdata[8];
          memset(readdata, 0, sizeof(readdata));
          if (ret = read(fd, readdata, sizeof(readdata))< 0)
          {
            printf("read fail:%s ", strerror(errno));
          }
          else
          {
            printf("readdata:%s, ret= %d ", readdata, ret);
          }
        }
        if (FD_ISSET(fd, &wfds))
        {
          printf("Device can be written now ");
          char writedata[8] = "abcdefg";
          if ((ret = write(fd, writedata, sizeof(writedata)))< 0)
          {
            printf("write fail:%s ", strerror(errno));
          }
          else
          {
            printf("writedata:%s, ret: %d ", writedata, ret);
          }
        }
      }

      close(fd);
      return 0;
    }

  • 相关阅读:
    48. Rotate Image
    83. Remove Duplicates from Sorted List
    46. Permutations
    HTML5笔记
    18. 4Sum
    24. Swap Nodes in Pairs
    42. Trapping Rain Water
    Python modf() 函数
    Python min() 函数
    Python max() 函数
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6279902.html
Copyright © 2011-2022 走看看