您所在的位置:读书频道 > 操作系统 > Linux > 1.2.7 poll接口

1.2.7 poll接口

2012-05-22 13:38 冯国进 机械工业出版社 我要评论(0) 字号:T | T

综合评级:

想读(9)  在读(2)  已读(1)   品书斋鉴(1)   已有12人发表书评

《Linux驱动程序开发实例》第1章 Linux设备驱动程序模型,本章主要介绍Linux内核中的驱动程序模型,包括三类设备的驱动程序、proc文件系统、Sysfs文件系统、Kobject等内容。本节为大家介绍poll接口。

AD: 51CTO云计算架构师峰会 抢票进行中!

1.2.7  poll接口

如果设备被配置成阻塞式操作,即当设备执行I/O操作时如果不能获得数据将阻塞,直到获得数据。应用层可以使用select函数查询设备当前的状态,以便用户程序获知是否能对设备进行非阻塞的访问。使用select函数需要在设备驱动程序中添加file_operations->poll接口支持。一个典型的字符驱动程序的file_operations->poll函数的实现如下:

  1. static unsigned int my_poll(struct file *file, struct poll_table_struct *wait)
  2. {
  3. unsigned int mask = 0;
  4. poll_wait(file, & outq, wait);//把当前进程添加到等待列表
  5. if (0 != bta->read_count)//如果有数据
  6. mask |= (POLLIN | POLLRDNORM);
  7. return mask;
  8. }

驱动程序中的poll函数返回的标志如下:

  1. #define POLLIN            1 //设备可以无阻塞地读取
  2. #define POLLPRI       2//可以无阻塞地读取高优先级数据(带外数据)
  3. #define POLLOUT       4//设备可以无阻塞地写入
  4. #define POLLERR       8//设备发生错误
  5. #define POLLHUP       16//当读取设备的进程到达文件尾部
  6. #define POLLNVAL          32 //请求无效
  7. #define POLLRDNORM    64//常规数据已经就绪
  8. #define POLLWRNORM  POLLOUT
  9. #define POLLRDBAND    128//可以从设备读带外数据
  10. #define POLLWRBAND    256//可以向设备写带外数据
  11. #define POLLMSG       0x0400
  12. #define POLLREMOVE   0x1000
  13. #define POLLRDHUP    0x2000

应用层多路I/O选择函数select的原型如下:

  1. int select(int numfds, fd_set *readfds, fd_set  *writefds, fd_set *exceptfds, struct timeval *timeout);

其中readfds、writefds、exceptfds分别是被select函数监视的读、写和异常处理的文件描述符集合,numfds的值是需要检查的号码最高的文件描述符加1。timeout参数是一个指向struct timeval类型的指针,它可以使select函数在等待timeout时间后若没有文件描述符准备好则返回。文件描述符集常用函数接口如下:

FD_ZERO(fd_set *set)//清除一个文件描述符集;

FD_SET(int fd,fd_set *set)//将文件描述符fd加入文件描述符集中;

FD_CLR(int fd,fd_set *set)//将文件描述符fd从文件描述符集中清除;

FD_ISSET(int fd,fd_set *set)//判断文件描述符fd是否被置位。

例1.7  poll接口驱动程序示例

代码见光盘\src\1drivermodel\1-7poll。核心代码如下所示:

  1. FD_ZERO(fd_set *set)//清除一个文件描述符集;
  2. FD_SET(int fd,fd_set *set)//将文件描述符fd加入文件描述符集中;
  3. FD_CLR(int fd,fd_set *set)//将文件描述符fd从文件描述符集中清除;
  4. FD_ISSET(int fd,fd_set *set)//判断文件描述符fd是否被置位。

例1.7  poll接口驱动程序示例

代码见光盘\src\1drivermodel\1-7poll。核心代码如下所示:

  1. ssize_t simple_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
  2. {
  3. //printk("wait_event_interruptible before\n");
  4. wait_event_interruptible(read_queue, simple_flag);
  5. //printk("wait_event_interruptible after\n");
  6. if (copy_to_user(buf,demoBuffer,count))
  7. {
  8. count=-EFAULT;
  9. }
  10. return count;
  11. }
  12. ssize_t simple_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
  13. {
  14. if (copy_from_user(demoBuffer, buf, count))
  15. {
  16. count = -EFAULT;
  17. goto out;
  18. }
  19. simple_flag=1;
  20. wake_up(&read_queue);
  21. out:
  22. return count;
  23. }
  24. //poll接口实现
  25. unsigned int simple_poll(struct file * file, poll_table * pt)
  26. {
  27. unsigned int mask = POLLIN | POLLRDNORM;
  28. poll_wait(file, &read_queue, pt);
  29. return mask;
  30. }
  31. struct file_operations simple_fops = {
  32. .owner =    THIS_MODULE,
  33. .poll =     simple_poll,
  34. .read =     simple_read,
  35. .write=     simple_write,
  36. .open =     simple_open,
  37. .release =  simple_release,
  38. };

应用程序参考代码如下:

  1. int fd;
  2. void *readthread(void *arg)//读数据线程
  3. {
  4. char data[256];
  5. fd_set rfds; //读描述符集合
  6. fd_set wfds; //写描述符集合
  7. int retval=0;
  8. while(1)
  9. {
  10. FD_ZERO(&rfds);
  11. FD_SET(fd, &rfds);
  12. select(fd+1, &rfds, &wfds, NULL, NULL); //多路选择
  13. if(FD_ISSET(fd, &rfds))
  14. {
  15. retval=read(fd,data,3);
  16. if(retval==-1)
  17. {
  18. perror("read error\n");
  19. exit(-1);
  20. }
  21. data[retval]=0;
  22. printf("read successfully:%s\n",data);
  23. }
  24. }
  25. return (void *)0;
  26. }
  27. void main()
  28. {
  29. int i;
  30. int retval;
  31. fd=open("/dev/fgj",O_RDWR);
  32. if(fd==-1)
  33. {
  34. perror("error open\n");
  35. exit(-1);
  36. }
  37. printf("open /dev/fgj successfully\n");
  38. pthread_t tid;
  39. pthread_create(&tid, NULL, readthread, NULL);//创建读线程
  40. while(1)
  41. {
  42. retval=write(fd,"fgj",3);//主线程负责写数据
  43. if(retval==-1)
  44. {
  45. perror("write error\n");
  46. exit(-1);
  47. }
  48. }
  49. close(fd);
  50. }

本例运行结果如下:

  1. [root@urbetter /home]# insmod demo.ko
  2. [root@urbetter /home]# mknod /dev/fgj c 224 0
  3. [root@urbetter /home]# ./test
  4. read successfully:fgj
  5. read successfully:fgj
  6. read successfully:fgj
  7. read successfully:fgj
  8. ...

poll接口《来自Linux驱动程序开发实例》相关推荐

  1. 异步通知《来自Linux驱动程序开发实例》

    您所在的位置:读书频道 > 操作系统 > Linux > 1.2.8 异步通知 1.2.8 异步通知 2012-05-22 13:38 冯国进 机械工业出版社 我要评论(0) 字号: ...

  2. 嵌入式Linux驱动程序开发

    嵌入式Linux驱动程序开发 1.设备驱动程序的概念... 2 2.处理器与设备间数据交换方式... 2 21.查询方式... 2 2.2.中断方式... 3 2.3.直接访问内存(DMA)方式... ...

  3. 基于DM6467的TVP7002 Linux驱动程序开发

    在Linux中,使用V4L2框架管理所有的视频编解码设备.针对我们开发板的V4L2框架结构已经在之前的TVP5150驱动程序编写和OV5642驱动程序编写的说明文档中进行了详细的分析,所以这里不再对整 ...

  4. linux驱动程序开发指南-字符驱动介绍

    概述: 在linux系统中设备驱动程序通常是作为应用层和设备层的中间层软件,驱动程序的主要功能是实现应用层访问硬件设备的具体操作接口,通过调用驱动程序,上层应用程序可以采用统一的接口访问各种硬件设备. ...

  5. Linux驱动程序开发 - 设备IO

    序言: 前面我们提到,设备驱动程序的主要功能操作设备,更准确的说就是如何操作设备寄存器或设备内存.不同的计算机体系结构提供了不同的设备操作接口,主要就是IO端口映射(Ports)或IO内存映射(Mem ...

  6. 4412在linux环境开发实例,Exynos4412交叉编译环境搭建

    交叉编译:在PC机(x86平台)上开发程序,在ARM板上运行,提高开发.编译速度. 环境: Tiny4412SDK1506开发板 需要软件: arm-linux-gcc-4.5.1-v6-vfp-20 ...

  7. Linux驱动(驱动程序开发、驱动框架代码编译和测试)

    目录 什么是驱动: 设备分类: 驱动认知: 字符设备驱动工作原理 字符设备.字符设备驱动与用户空间访问该设备的程序三者之间的关系 驱动程序开发步骤 基于驱动框架的代码开发 驱动模块代码编译和测试 加载 ...

  8. 目录 - 《ARM嵌入式Linux系统开发从入门到精通》 - 免费试读 - book.csdn.net

    第一部分 ARM Linux系统移植 第1章 嵌入式系统开发入门...... 2 1.1 嵌入式系统介绍..... 2 1.1.1 嵌入式系统概述..... 2 1.1.2 嵌入式系统组成..... ...

  9. Linux驱动程序教程:如何编写简单的Linux设备驱动程序

    翻译来自: https://www.apriorit.com/dev-blog/195-simple-driver-for-linux-os 代码下载 此Linux设备驱动程序教程将为您提供有关如何为 ...

最新文章

  1. java中的多态_Java中的多态
  2. 基于尺寸划分的RGB显著物体检测方法
  3. Python多任务(7.多进程的应用:文件的拷贝器例子)
  4. 基于注意力机制的知识图谱关系预测 ACL 2019
  5. 实验8.1 链表类的定义与实现
  6. ## CSP 201809-2 买菜(C语言)(100分)
  7. 斐波那契数列的第N项
  8. python-pip : Depends: python-setuptools (= 0.6c1) 问题
  9. android 高通替换开机logo,高通平台 开机logo 替换
  10. 鸿蒙界境界划分,修为境界划分
  11. redis报错NOAUTH Authentication required.
  12. sip php 来电,php - 如何在Twilio上传递原来的来电显示? (Sip域语音URL配置) - SO中文参考 - www.soinside.com...
  13. JAVA方式对接FIL节点钱包(也有离线)
  14. 第四周day19-三剑客之awk
  15. 7-2 拍7令四 (100 分)
  16. cocos2dX 之音乐与音效
  17. 外汇交易与实务--即期外汇交易
  18. 爬虫2_2019年549所中国大学排名
  19. 从零开始学C语言 : 初阶指针
  20. 学习日志13:360安全浏览器远程代码执行漏洞

热门文章

  1. 小学三年级计算机导学案,小学三年级学科导学案.doc
  2. 虎牙游戏直播基于php swoole,centos6.8 php7+swoole 实现赛事直播系统
  3. 因为计算机中丢失ssce5432.dll,ssce5432.dll 64位
  4. xamppmysql访问被拒绝_XAMPP中无法开始MySQL的问题
  5. Java怎么跑不起来_tarsJava example 跑不起来
  6. 收集、分析线上日志数据实战——ELK
  7. pandas dataframe 一行变多行 (query pv统计term pv)
  8. msp单片机UCS配置
  9. centos mysql 实战 第一节课 安全加固 mysql安装
  10. 【线段树】HDU 3397 Sequence operation 区间合并