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;
    }

  • 相关阅读:
    display值的作用分别是什么?relative和absolute分别是相对谁定位的?
    CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算?
    position的absolute与fixed共同点与不同点
    .net core实践系列之SSO-同域实现
    .net core实践系列之短信服务-Sikiro.SMS.Job服务的实现
    .net core实践系列之短信服务-Sikiro.SMS.Bus服务的实现
    .net core实践系列之短信服务-Api的SDK的实现与测试
    .net core实践系列之短信服务-Sikiro.SMS.Api服务的实现
    .net core实践系列之短信服务-为什么选择.net core(开篇)
    winserver的consul部署实践与.net core客户端使用(附demo源码)
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6279902.html
Copyright © 2011-2022 走看看