您当前的位置:首页 > 电脑百科 > 软件技术 > 操作系统 > linux

Linux驱动基石之POLL机制

时间:2020-09-03 10:49:09  来源:  作者:

来源:百问网

作者:韦东山

本文字数:2344,阅读时长:4分钟

1.适用场景

在前面引入中断时,我们曾经举过一个例子:

Linux驱动基石之POLL机制

 

妈妈怎么知道卧室里小孩醒了?

  1. 时不时进房间看一下:查询方式
    简单,但是累
  2. 进去房间陪小孩一起睡觉,小孩醒了会吵醒她:休眠-唤醒
    不累,但是妈妈干不了活了
  3. 妈妈要干很多活,但是可以陪小孩睡一会,定个闹钟:poll方式
    要浪费点时间,但是可以继续干活。妈妈要么是被小孩吵醒,要么是被闹钟吵醒。
  4. 妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈:异步通知
    妈妈、小孩互不耽误

使用休眠-唤醒的方式等待某个事件发生时,有一个缺点:等待的时间可能很久。我们可以加上一个超时时间,这时就可以使用poll机制。

  1. App不知道驱动程序中是否有数据,可以先调用poll函数查询一下,poll函数可以传入超时时间;
  2. APP进入内核态,调用到驱动程序的poll函数,如果有数据的话立刻返回;
  3. 如果发现没有数据时就休眠一段时间
  4. 当有数据时,比如当按下按键时,驱动程序的中断服务程序被调用,它会记录数据、唤醒APP;
  5. 当超时时间到了之后,内核也会唤醒APP;
  6. APP根据poll函数的返回值就可以知道是否有数据,如果有数据就调用read得到数据

 

2.使用流程

妈妈进入房间时,会先看小孩醒没醒,闹钟响之后走出房间之前又会再看小孩醒没醒。
注意:看了2次小孩!
POLL机制也是类似的,流程如下:

Linux驱动基石之POLL机制

 

函数执行流程如上图①~⑧所示,重点从③开始看。假设一开始无按键数据:

③ APP调用poll之后,进入内核态;
④ 导致驱动程序的drv_poll被调用:
注意,drv_poll要把自己这个线程挂入等待队列wq中;假设不放入队列里,那以后发生中断时,中断服务程序去哪里找到你嘛?
drv_poll还会判断一下:有没有数据啊?返回这个状态。
⑤ 假设当前没有数据,则休眠一会;
⑥ 在休眠过程中,按下了按键,发生了中断:
在中断服务程序里记录了按键值,并且从wq中把线程唤醒了。
⑦ 线程从休眠中被唤醒,继续执行for循环,再次调用drv_poll:
drv_poll返回数据状态
⑧ 哦,你有数据,那从内核态返回到应用态吧
⑨ APP调用read函数读数据
如果一直没有数据,调用流程也是类似的,重点从③开始看,如下:
③ APP调用poll之后,进入内核态;
④ 导致驱动程序的drv_poll被调用:
注意,drv_poll要把自己这个线程挂入等待队列wq中;假设不放入队列里,那以后发生中断时,中断服务程序去哪里找到你嘛?
drv_poll还会判断一下:有没有数据啊?返回这个状态。
⑤ 假设当前没有数据,则休眠一会;
⑥ 在休眠过程中,一直没有按下了按键,超时时间到:内核把这个线程唤醒;
⑦ 线程从休眠中被唤醒,继续执行for循环,再次调用drv_poll:
drv_poll返回数据状态
⑧ 哦,你还是没有数据,但是超时时间到了,那从内核态返回到应用态吧
⑨ APP不能调用read函数读数据

注意几点:

  1. drv_poll要把线程挂入队列wq,但是并不是在drv_poll中进入休眠,而是在调用drv_poll之后休眠
  2. drv_poll要返回数据状态
  3. APP调用一次poll,有可能会导致drv_poll被调用2次
  4. 线程被唤醒的原因有2:中断发生了去队列wq中把它唤醒,超时时间到了内核把它唤醒
  5. APP要判断poll返回的原因:有数据,还是超时。有数据时再去调用read函数。

 

3. 驱动编程

使用poll机制时,驱动程序的核心就是提供对应的drv_poll函数。
在drv_poll函数中要做2件事:

  1. 把当前线程挂入队列wq:poll_wait
    APP调用一次poll,可能导致drv_poll被调用2次,但是我们并不需要把当前线程挂入队列2次。可以使用内核的函数poll_wait把线程挂入队列,如果线程已经在队列里了,它就不会再次挂入。
  2. 返回设备状态:
    APP调用poll函数时,有可能是查询“有没有数据可以读”:POLLIN,也有可能是查询“你有没有空间给我写数据”:POLLOUT。所以drv_poll要返回自己的当前状态:(POLLIN | POLLRDNORM) 或 (POLLOUT | POLLWRNORM)。POLLRDNORM等同于POLLIN,为了兼容某些APP把它们一起返回。POLLWRNORM等同于POLLOUT ,为了兼容某些APP把它们一起返回。

 

APP调用poll后,很有可能会休眠。对应的,在按键驱动的中断服务程序中,也要有唤醒操作。
驱动程序中poll的代码如下:

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

 

4 应用编程

注意:APP可以调用poll或select函数,这2个函数的作用是一样的。
poll/select函数可以监测多个文件,可以监测多种事件:
事件类型 说明
POLLIN 有数据可读
POLLRDNORM 等同于POLLIN
POLLRDBAND Priority band data can be read,有优先级较较高的“band data”可读
linux系统中很少使用这个事件
POLLPRI 高优先级数据可读
POLLOUT 可以写数据
POLLWRNORM 等同于POLLOUT
POLLWRBAND Priority data may be written
POLLERR 发生了错误
POLLHUP 挂起
POLLNVAL 无效的请求,一般是fd未open



Tags:POLL机制   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
使用休眠-唤醒的方式等待某个事件发生时,有一个缺点:等待的时间可能很久。我们可以加上一个超时时间,这时就可以使用poll机制。...【详细内容】
2020-09-03  Tags: POLL机制  点击:(105)  评论:(0)  加入收藏
前言 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基1. 概述Linux系统在访问设备的时候,存在以下几种IO模型: Blocking IO Mode...【详细内容】
2020-09-01  Tags: POLL机制  点击:(74)  评论:(0)  加入收藏
▌简易百科推荐
作用显示文件或目录所占用的磁盘空间使用命令格式du [option] 文件/目录命令功能显示文件或目录所占用的磁盘空间一些写法的区别du -sh xxx 显示总目录的大小,但是不会列出...【详细内容】
2021-12-23  mitsuhide1992    Tags:du命令   点击:(12)  评论:(0)  加入收藏
什么是linux内核linux就像是一个哲学的最佳实践。如果非要对它评价,我真的不知道该怎么赞叹,我只能自豪地说着:“linux的美丽简直让人沉醉。”我只能说是我处在linux学习的修炼...【详细内容】
2021-12-23  linux上的码农    Tags:linux内核   点击:(15)  评论:(0)  加入收藏
本文将比较 Linux 中 service 和 systemctl 命令,先分别简单介绍这两个命令的基础用法,然后进行比较。从 CentOS 7.x 开始,CentOS 开始使用 systemd 服务来代替 service服务(dae...【详细内容】
2021-12-23  软件架构    Tags:systemctl   点击:(13)  评论:(0)  加入收藏
mv是move的缩写,可以用来移动文件或者重命名文件名,经常用来备份文件或者目录。命令格式mv [选项] 源文件或者目录 目标文件或者目录命令功能mv命令中第二个参数类型的不同(...【详细内容】
2021-12-17  入门小站    Tags:mv命令   点击:(23)  评论:(0)  加入收藏
大数据技术AI Flink/Spark/Hadoop/数仓,数据分析、面试,源码解读等干货学习资料 98篇原创内容 -->公众号 Linux sed 命令是利用脚本来处理文本文件。sed 可依照脚本的指令来处...【详细内容】
2021-12-17  仙风道骨的宝石骑士    Tags:sed命令   点击:(21)  评论:(0)  加入收藏
Node是个啥?  写个东西还是尽量面面俱到吧,所以有关基本概念的东西我也从网上选择性地拿了下来,有些地方针对自己的理解有所改动,对这些概念性的东西有过了解的可选择跳过这段...【详细内容】
2021-12-15  linux上的码农    Tags:node   点击:(21)  评论:(0)  加入收藏
难道只有我一个人觉得Ubuntu的unity桌面非常好用吗?最近把台式机上面的Ubuntu 16.04格式化了,装了黑苹果用了一周,不得不说,MacOS确实很精美,软件生态比Linux丰富很多,比Windows简...【详细内容】
2021-12-14  地球末日村    Tags:ubuntu   点击:(34)  评论:(0)  加入收藏
简介Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。输出信息含义执行net...【详细内容】
2021-12-13  窥镜天    Tags:Linux netstat   点击:(26)  评论:(0)  加入收藏
对于较多数量的文件描述符的监听无论是select还是poll系统调用都显得捉襟见肘,poll每次都需要将所有的文件描述符复制到内核,内核本身不会对这些文件描述符加以保存,这样的设计...【详细内容】
2021-12-13  深度Linux    Tags:Linux   点击:(16)  评论:(0)  加入收藏
今天,我们来了解下 Linux 系统的革命性通用执行引擎-eBPF,之所以聊着玩意,因为它确实牛逼,作为一项底层技术,在现在的云原生生态领域中起着举足轻重的作用。截至目前,业界使用范...【详细内容】
2021-12-10  架构驿站    Tags:eBPF   点击:(24)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条