设备驱动基础学习--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\n", 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\n");
              char readdata[8];
              memset(readdata, 0, sizeof(readdata));
              if (ret = read(fd, readdata, sizeof(readdata))< 0)
              {
                    printf("read fail:%s\n", strerror(errno));
              }
              else
              {
                    printf("readdata:%s, ret= %d\n", readdata, ret);
              }
          }
          if (FD_ISSET(fd, &wfds))
          {
      	      printf("Device can be written now\n");
              char writedata[8] = "abcdefg";
              if ((ret = write(fd, writedata, sizeof(writedata)))< 0)
              {
                    printf("write fail:%s\n", strerror(errno));
              }
              else
              {
                    printf("writedata:%s, ret: %d\n", writedata, ret);
              }
          }
      }
  close(fd);
      return 0;
}
设备驱动基础学习--poll的更多相关文章
- 设备驱动基础学习--platform driver简单实现
		
platform是一条虚拟的总线.设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device drive ...
 - 设备驱动基础学习--misc device简单实现
		
在Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述).miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同. 所有的miscde ...
 - 设备驱动基础学习--/proc下增加节点
		
在需要创建一个由一系列数据顺序组合而成的/proc虚拟文件或一个较大的/proc虚拟文件时,推荐使用seq_file接口. 数据结构struct seq_fille定义在include/linux/s ...
 - Hasen的linux设备驱动开发学习之旅--时钟
		
/** * Author:hasen * 參考 :<linux设备驱动开发具体解释> * 简单介绍:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:时钟 * Date ...
 - 字符设备驱动(六)按键poll机制
		
title: 字符设备驱动(六)按键poll机制 tags: linux date: 2018-11-23 18:57:40 toc: true --- 字符设备驱动(六)按键poll机制 引入 在字 ...
 - Introduction the naive“scull”  《linux设备驱动》 学习笔记
		
Introduction the naive "scull" 首先.什么是scull? scull (Simple Character Utility for Loading Lo ...
 - 【驱动】Flash设备驱动基础·NOR·NAND
		
Flash存储器 ——>Flash存储器是近几年来发展最快的存储设备,通常也称作闪存.Flash属于EEPROM(电可擦除可编程只读存储器),是一类存取速度很高的存储器. ——>它既有RO ...
 - 3.字符设备驱动------Poll机制
		
1.poll情景描述 以之前的按键驱动为例进行说明,用阻塞的方式打开按键驱动文件/dev/buttons,应用程序使用read()函数来读取按键的键值. ) { read(fd, &key_v ...
 - Linux内核分析(五)----字符设备驱动实现
		
原文:Linux内核分析(五)----字符设备驱动实现 Linux内核分析(五) 昨天我们对linux内核的子系统进行简单的认识,今天我们正式进入驱动的开发,我们今后的学习为了避免大家没有硬件的缺陷, ...
 
随机推荐
- [P3935] Calculating - 整除分块
			
容易发现题目要求的 \(f(x)\) 就是 \(x\) 的不同因子个数 现在考虑如何求 \(\sum_{i=1}^n f(i)\),可以考虑去算每个数作为因子出现了多少次,很容易发现是 \([n/i] ...
 - app点击底部菜单切换标题
			
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <meta name=& ...
 - Copy Paste DWG to older 3ds Max
			
Hi, This is quick tutorial: how to install Auto Cad scripts to be able to copy from newer Auto Cad t ...
 - C语言--“.”与“->”有什么区别?
			
这虽然是个小问题,但有时候很容易让人迷惑,因为有的时候用混淆了,程序编译不通过. 下面说说我对它们的理解. 一般情况下用“.”,只需要声明一个结构体.格式是,结构体类型名+结构体名.然后用结构 ...
 - MySQL | 查看log日志
			
1. 进入mysql mysql -u用户名 -p密码 2. 开启日志 et global general_log=on: 3. 查看mysql日志文件的路径 show variables like ...
 - AspxDashBorad_OnDashboardLoaded  获取对应的DashboardParameter
			
protected void ASPxDashboardViewerThrend_OnDashboardLoaded(object sender, DashboardLoadedWebEventArg ...
 - flask入门(二)
			
接着上文 讲一讲响应 flask调用视图函数后,会将其返回值作为响应的内容.大多数情况下,响应就是一个简单的字符串,作为HTML页面回送客户端.但HTTP协议需要的不仅是作为请求响应的字符串.HTTP ...
 - C++索引从0开始的堆排序算法实现
			
更新2019年11月4日 04:26:35 睡不着觉起来寻思寻思干点啥吧,好像好久没写堆排了.于是写了个索引从0开始的堆排,这次把建堆函数略了并在heapsort主函数里,索引从0开始到size-1结 ...
 - 零Web知识个性化Blog
			
需要使用到的工具 Chrome Pycharm 自定主题的CSS 申请博客的Js权限 设置博客选项 打开Chrome修改查看CSS样式,Windows(F12),MacOS(Command+Optio ...
 - OpenCV——仿射变换
			
什么是仿射变换? 一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移). 综上所述, 我们能够用仿射变换来表示: 旋转 (线性变换) 平移 (向量加) 缩放操作 ( ...