【linux】驱动-14-异步通知
前言
14. 异步通知
本章内容为驱动基石之一。
驱动只提供功能,不提供策略。
阻塞与非阻塞是 APP 询问 驱动设备。
异步通知是 驱动设备 主动通知 APP。
原文:https://www.cnblogs.com/lizhuming/p/14918049.html
14.1 异步通知的一些概念
异步通知:一旦设备就绪,则主动通知APP,这样APP就不用轮询查询设备状态了。
异步IO:APP 发起 IO 请求后,立即返回。然后再查询 IO 完成情况,或者 IO 完成后被调回。这个过程叫做 异步IO。
14.2 Linux 信号
可以使用 信号 来进行进程间通信(IPC)。
Linux信号表:
- 路径参考:include\uapi\asm-generic\signal.h
| 信号 | 值 | 说明 |
|---|---|---|
| SIGHUP | 1 | 挂起 |
| SIGINT | 2 | 中断中断 |
| SIGQUIT | 3 | 终端退出 |
| SIGILL | 4 | 无效命令 |
| SIGTRAP | 5 | 跟踪陷阱 |
| SIGABRT | 6 | 异常终止信号,和 SIGIOT 同义 |
| SIGIOT | 6 | IOT陷阱,和 SIGABRT 同义 |
| SIGBUS | 7 | BUS错误 |
| SIGFPE | 8 | 浮点异常 |
| SIGKILL | 9 | 强制终止 |
| SIGUSR1 | 10 | 用户自定义信号1 |
| SIGSEGV | 11 | 无效的内存段处理 |
| SIGUSR2 | 12 | 用户自定义信号2 |
| SIGPIPE | 13 | 半关闭管道的写操作 |
| SIGALRM | 14 | 计时器到期 |
| SIGTERM | 15 | 终止 |
| SIGSTKFLT | 16 | 堆栈错误 |
| SIGCHLD | 17 | 子进程已经停止或退出 |
| SIGCONT | 18 | 如果停止了,继续执行 |
| SIGSTOP | 19 | 停止执行 |
| SIGTSTP | 20 | 终端停止信号 |
| SIGTTIN | 21 | 后台进程需要从终端读取输入 |
| SIGTTOU | 22 | 后台进程需要从终端写出 |
| SIGURG | 23 | 紧急的套接字事件 |
| SIGXCPU | 24 | 超额使用CPU分配的时间 |
| SIGXFSZ | 25 | 文件尺寸超额 |
| SIGVTALRM | 26 | 虚拟时钟信号 |
| SIGPROF | 27 | 时钟信号描述 |
| SIGWINCH | 28 | 出口尺寸变化 |
| SIGIO | 29 | I/O |
| SIGPOLL | SIGIO | I/O |
除了 SIGSTOP 和 SIGKILL 两个信号外,进程能够忽略或捕获其它所有信号。
一个信号被捕获的意思是当一个信号到达时有相应代码处理它。
如果一个信号没有被这进程所捕获,内核将采取默认行为处理。
14.3 信号接收
14.4 使用流程
14.4.1 参考流程图
流程图参考韦东山:
14.4.2 分析&编程步骤
分析中的细节部分会在后本节后面说明
分析:
②:绑定信号与回调函数。使用
sighandler_t signal(int signum, sighandler_t handler)。③:把 APP PID 告诉内核。同时,该 PID 会保存到该驱动的内核文件 file 结构体中。
④:读取该驱动程序文件的 Flag。
⑤:设置 Flag 里面的 FASYNC 位为 1。当 FASYNC 位发生变化时,该驱动会调用驱动操作
drv_fasync函数。⑥:驱动开发者实现的函数。主要是调用 fasync_helper 函数。
⑦:调用 fasync_helper() 函数,主要是把 驱动程序内核文件 file 结构体绑定到 button_async->fa_file 中。而 file 包含了 APP 的 PID。所以发送信号时,只需要使用 button_async 作为参数即可。
⑩:发送信号给对应的 APP。参数为 button_async。
注:button_async 结构体由驱动开发者创建,维护。
APP 信号编程步骤:
- ①:编写信号回调函数。
- ②:绑定信号与回调函数。
- ③:打开驱动。
- ④:获取 PID ,告知内核。
- ⑤:获取进程状态值。
- ⑥:当前状态值添加异步功能,出发调用驱动异步处理函数。
KERNEL 信号编程步骤:
- ①:定义异步结构体。
- ②:实现异步操作函数,并把该函数填充到设备内核驱动操作结构体中。
- 该函数内容主要调用 fasync_helper() 函数,初始化异步结构体。(把 file ,内核PID,交给异步结构体)
- ③:发送信号。
14.4.3 使用函数说明
14.4.3.1 相关结构体及参考模型
APP 模型 截段:
......
/* 设置信号 SIGIO 的处理函数 */
signal(SIGIO, sigio_signal_func);
fcntl(fd, F_SETOWN, getpid()); /* 将当前进程的进程号告诉给内核 */
flags = fcntl(fd, F_GETFD); /* 获取当前的进程状态 */
fcntl(fd, F_SETFL, flags | FASYNC); /* 设置进程启用异步通知功能。会调用驱动中的 drv_fasync 函数 */
......
fasync_struct:
- (在内核源码中,目前没有去找内核文档该结构体内容的相关信息)
struct fasync_struct {
rwlock_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;
};
14.4.3.2 signal 函数
APP 使用。
函数原型:sighandler_t signal(int signum, sighandler_t handler) :
- 功能:绑定信号与回调函数。
- signum:信号类型。除 SIGKILL 和 SIGSTOP 外的任何一种信号。
- handler:该参数有三种类型。
- ①:SIG_IGN 类型。表示忽略该信号。
- ②:SIG_DFL 类型。表示恢复对信号的系统默认处理。
- ③:sighandler_t 类型的函数指针。即是回调函数。
typedef void (*sighandler_t)(int);。
- 注:APP 收到信号执行回调函数时,signum 参数会被传到回调函数的形参传递给回调函数。即是回调函数的形参就是信号类型。
14.4.3.3 kill_fasync 函数
KERNEL 使用。
函数原型:void kill_fasync(struct fasync_struct **fp, int sig, int band) :
- 功能:发送信号给 fp 参数绑定的进程。(by PID)
- 参考路径:linux-5.12.8\fs\fcntl.c
- fp:需要操作的 fasync_struct。
- sig:信号类型。
- band:可读时设置为 POLL_IN;可写时设置为 POLL_OUT。当然该参数还可以填
POLL_MSG。以上三个值在应用层接收时,si_code 分别为 0x01、0x02、0x03。
【linux】驱动-14-异步通知的更多相关文章
- Linux驱动之异步通知的应用
前面的按键驱动方式都是应用程序通过主动查询的方式获得按键值的: 1.查询方式 2.中断方式 3.poll机制 下面介绍第四种按键驱动的方式 4.异步通知:它可以做到应用程序不用随时去查询按键的状态,而 ...
- linux驱动的异步通知(kill_fasync,fasync)---- 驱动程序向应用程序发送信号
应用程序 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include < ...
- 蜕变成蝶~Linux设备驱动之异步通知和异步I/O
在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问.因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代.异步通知类 ...
- linux下使用异步通知
阻塞式I/O是一直等待直到设备可以访问,非阻塞式I/O是定期轮询设备是否可以访问. 异步通知则是当设备可以访问时才主动通知应用程序,有点像设备的硬中断. 并不是所有的设备都支持异步通知,应用程序通常假 ...
- Linux通信之异步通知模式
[参考]韦东山 教学笔记 为了使设备支持异步通知机制,驱动程序中涉及以下3项工作:1. 支持F_SETOWN命令,能在这个控制命令处理中设置filp->f_owner为对应进程ID. 不过此项工 ...
- Linux驱动之异步OR同步,阻塞OR非阻塞概念介绍
链接:https://www.zhihu.com/question/19732473/answer/20851256 1.同步与异步同步和异步关注的是消息通信机制 (synchronous commu ...
- Linux学习 :按键信号 之 异步通知
一.异步通知概念: 异步通知是指:一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态,类似于中断的概念,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进 ...
- linux异步通知
简述 linux下异步方式有两种:异步通知和异步IO(AIO),aio请参考:linux异步IO--aio 异步通知的含义是:一旦设备就绪,则主动通知应用程序,这样应用程序就不需要查询设备状态,准确称 ...
- Linux内核开发之异步通知与异步I/O(一)
“小王,听说过锦上添花吧..”我拍拍下王的头说. “还锦上添花你,为你上次提的几个东东,我是头上长包..”小王气愤地瞪着我. “啊,为啥这样呢,本来还特意拒绝了MM的月份,抽出时间打算给你说点高级的东 ...
随机推荐
- 前端用网址生成二维码(jquery)
1.加载jquery.qrcode.min.js 2.html部分: 3.js部分:url为生成二维码的网址 附: jquery.qrcode.min.js下载 链接:https://pan.baid ...
- SQL必学必会笔记 —— 基础篇
基础篇 SQL语言按照功能划分 DDL(DataDefinitionLanguage),也就是数据定义语言,它用来定义我们的数据库对象,包括 数据库.数据表和列.通过使用DDL,可以创建,删除和修改数 ...
- springboot 项目中css js 等静态资源无法访问的问题
目录 问题场景 问题分析 问题解决 问题场景 今天在开发一个springboot 项目的时候突然发现 css js 等静态资源竟然都报404找不到,折腾了好久终于把问题都解决了,决定写篇博客,纪录总结 ...
- Git 系列教程(7)- 撤销操作
撤销操作 在任何一个阶段,你都有可能想要撤销某些操作 有些撤销操作是不可逆的 --amend 修补提交 有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了. 此时,就可以运行带有 -- ...
- Codeforces Round #688 (Div. 2)
A. Cancel the Trains 题意:给定两个数组,找出这两个数组中有多少重复元素,然后输出 思路:直接找 代码: 1 #include<iostream> 2 #include ...
- 判断标准I/O的缓冲区类型
#include <stdio.h> void pr_stdio(const char *, FILE *); int main() { FILE *fp; fputs("ent ...
- Java方法区的理解
方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩. 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开 所以方法区看作是一块 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格
多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...
- [c++] 文件包含
当一个类用到另一个类时,有两种包含方式,在.h中包含和在.cpp中包含 用到公共类库时,在.h文件中包含(公共类库可视为不变的) 用到项目开发过程中自己或同事写的类时,在.cpp文件中包含(可能根据需 ...
- 单用户模式修改root密码
单用户模式修改root密码 1.进入引导菜单界面2.按e进入grub,在linux或linux16那行结尾加上 rw init=/bin/bash,按Ctrl+x或F103.进入bash-4.3# , ...
