异步通知的全称是"信号驱动的异步IO",通过"信号"的方式,放期望获取的资源可用时,驱动会主动通知指定的应用程序,和应用层的"信号"相对应,这里使用的是信号"SIGIO"。操作步骤是

  1. 应用层程序将自己注册为接收来自设备文件的SIGIO信号的进程
  2. 驱动实现相应的接口,以期具有向所有注册接收这个设备驱动SIGIO信号的应用程序发SIGIO信号的能力。
  3. 驱动在适当的位置调用发送函数,应用程序即可接收到SIGIO信号。

整个机制的框架:

应用层接收SIGIO

和其他信号一样,应用层需要注册一个信号处理函数,
注册的方式还是使用signal()sigaction()

此外,应用层还需要把自己加入到驱动的通知链表中,加入的代码如下

fcntl(dev_fd,F_SETOWN,getpid());
int oflags = fcntl(dev_fd,F_GETFL);
fcntl(dev_fd,F_SETFL,oflags|FASYNC);
...
while(1);

完成了上面的工作,应用层的程序就可以静待SIGIO的到来了。

驱动发送SIGIO

应用层注册好了,最终的发送还是看设备驱动的处理方式,为了使设备支持异步通知机制,参照应用层的接口,驱动程序中涉及3项工作。

  1. 支持F_SETOWN命令,能在这个命令中下设置filp->f_owner为对应进程的ID,这部分内核已经做了
  2. 支持F_SETFL,每当FASYNC标志改变时,驱动程序中的fasync()将得以执行,so,驱动中要实现fasync()
  3. 当设备资源可用时,通过kill_fasync()发送SIGIO

为了在内核中实现上面这三个功能,驱动需要使用1个结构+2个API,结构是struct fasync_struct,函数是fasync_helper()kill_fasync()

struct fasync_struct {                                    spinlock_t              fa_lock;int                     magic;int                     fa_fd;struct fasync_struct    *fa_next; /* singly linked list */struct file             *fa_file;struct rcu_head         fa_rcu;
};

fasync_helper()的作用是将一个fasync_struct的对象注册进内核,应用层执行fcntl(dev_fd,F_SETFL,oflags|FASYNC)时会回调驱动的fops.fasync(),所以通常将fasync_helper()放到fasync()的实现中。

/***fasync_helper - 将一个fasync_struct对象注册进内核*@fd:文件描述符,由fasync传入*@filp:file指针,由fasync传入*@sig:信号类型,通常使用的就是SIGIO*@dev_fasync:事前准备的fasync_struct对象指针的指针*/
int fasync_helper(int fd, struct file * filp, int sig, struct fasync_struct ** dev_fasync);   

下面这个API就是释放SIGIO,根据需求的不同放到不同的位置。

/***kill_fasync - 释放一个信号*@dev_fasync:事前使用fasync_helper注册进内核的fasync_struct对象指针的指针*@filp:file指针,由fasync传入*@sig:信号类型,通常使用的就是SIGIO*@flag:标志,通常,如果资源可读用POLLIN,如果资源可写用POLLOUT*/
void kill_fasync(struct fasync_struct **dev_fasync, int sig, int flag);

驱动模板

下面这个驱动模板针对在硬件中断到来(资源可用)的时候向应用层发信号,实际的操作中表明资源可用的情境还有很多

static struct fasync_struct *fasync = NULL;static irqreturn_t handler(int irq, void *dev)
{kill_fasync(&fasync, SIGIO, POLLIN);return IRQ_HANDLED;
}
static int demo_fasync(int fd, struct file *filp, int mode)
{return fasync_helper(fd, filp, mode, &fasync);
}
struct file_operations fops = {....fasync = demo_fasync,...
}
static int __init demo_init(void)
{...request_irq(irq, handler, IRQF_TRIGGER_RISING, "demo", NULL);...
}

转载于:https://www.cnblogs.com/xiaojiang1025/p/6376561.html

Linux驱动技术(四) _异步通知技术相关推荐

  1. 可穿戴技术发展阶段_可穿戴技术如何改变我们与身体的关系

    可穿戴技术发展阶段 It's no secret that wearable tech has gained traction over the past years. Its buyers have ...

  2. 智能网联技术 英文_智能网联技术是什么?有什么好推荐学习地方?

    展开全部 智能bai网联汽车是指搭载du先进的车载传感zhi器.控制器.执行器等装置,并融dao合现内代通信与网络技术,实现车与容车.路.人.云等智能信息交换.共享. 具备复杂环境感知.智能决策.协同 ...

  3. 区块链是大数据生态圈技术之一_区块链技术再发力,携手智能制造构建产业生态圈...

    原标题:区块链技术再发力,携手智能制造构建产业生态圈 大数据时代的逐渐逼近,使得传统行业面临巨大的挑战.区块链技术是大数据时代备受关注的新星,在越来越多的领域进行试点应用,区块链技术也是大数据时代日益 ...

  4. linux 驱动笔记(四)

    第六章 GPIO的标准接口函数 1 什么是GPIO的标准接口函数 思考: 1.1设计GPIO驱动的方法??? 1.1.1 找到配置/控制GPIO的寄存器,得到了访问该寄存器的物理地址 1.1.2 申请 ...

  5. 微信语音技术原理_智能语音技术中麦克风阵列的原理

    麦克风阵列(Microphone Array),从字面上,指的是麦克风的排列.也就是说由一定数目的声学传感器(一般是麦克风)组成,用来对声场的空间特性进行采样并处理的系统. 早在20世纪70.80年代 ...

  6. dll可以在linux下使用吗_无需虚拟技术,6步直接在Windows下使用Linux

    Windows和Linux是大家熟知并且常用的两大操作系统.相信每一个使用计算机的人,都至少使用过它们其中之一.但由于它们之间的竞争关系和不同内核技术.所以我们一直认为它们之间很难共存,虽然伴随着虚拟 ...

  7. linux字符设备驱动之字符之异步通知

    在前面的博文中记录的都是应用层主动查询读取驱动按键状态.驱动可不可以在有信号之后,主动上报通知应用层事件呢?当然可以,linux如此博大精深.我们使用异步通信机制,signal的办法实现该功能. 所谓 ...

  8. 网络对抗技术_实验四_恶意代码技术

    中国人民公安大学 Chinese people' public security university 网络对抗技术 实验报告   实验四 恶意代码技术     学生姓名 韩磊 年级 2014 区队 ...

  9. 从零开始之驱动发开、linux驱动(四十、Linux common clock framework(5)_使用举例)

    前面三节分析的3.16.57内核中,三星的驱动中,恰好S5PV210的CPU没有使用Linux common clock framework来处理clk.所以,本文采用4.9.92的内核来分析S5PV ...

最新文章

  1. 如何减少WIN7响应时间
  2. 汇编: loop指令
  3. OpenCV学习之路之OpenCV安装(VS2013版)
  4. 【Linux入门连载一】[Win10下安装Linux虚拟机]VMWare15运行CentOS7(亲测有效)
  5. Visual C# 2008+SQL Server 2005 数据库与网络开发--9.1.1 SQL Server 2005中的XML功能
  6. C#设计模式(9)——装饰者模式(Decorator Pattern)
  7. 编程开发之--java多线程学习总结(3)类锁
  8. Resid 学习笔记1-基础命令
  9. httppostedfilebase.saveas后文件被占用_文件过多时ls命令为什么会卡住?
  10. Scrapy_CSS选择器
  11. Head First设计模式之命令模式
  12. 呼吸灯程序(非阻塞)
  13. 高等数学(下)知识点总结(1)
  14. wireshark抓取分析UDP数据包
  15. NGINX转发udp、tcp
  16. 百度AI开放平台情感分类
  17. 通俗易懂的Bootstrap视频课程(适合初学者的教程)-汤小洋-专题视频课程
  18. ROS创建Web代理(Web proxy)
  19. 人脸颜值预测(facial beauty prediction)综述
  20. .jar是什么文件?(转载)

热门文章

  1. 编程统计BUF字单元数据中所含1的个数,并将结果存入COUNT单元中。
  2. 方法之输出星型及其调用
  3. A+B Problem(V)
  4. redis 备份导出rdb_Redis数据迁移利器之redisshake
  5. uva 10515——Powers Et Al.
  6. Ubuntu修复Fix Busybox Initramfs错误
  7. 【C++11新特性】 C++11智能指针之shared_ptr
  8. 从0到1写RT-Thread内核——临界段的保护
  9. Java-进阶:Java-File--IO—1
  10. docker环境 快速使用elasticsearch-head插件