Linux驱动IO篇——异步通知

在这里插入图片描述

文章目录

    • 什么是异步通知
    • 异步通知和异步IO的区别
    • 信号含义
    • 应用层使用信号
    • 驱动如何实现异步信号
    • 驱动实例

什么是异步通知


异步通知在Linux的实现中是通过信号,而信号是在软件层次上对中断机制的一种模拟。这种机制和中断非常类似,所以可以以中断的思想来理解这一过程,信号其实就相当于应用层的中断。

信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。

如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。

异步通知和异步IO的区别


异步通知:当资源可获得时,由驱动程序向应用层发送一个信号,主动通知应用程序,再由应用程序发起访问。

异步IO主动获取设备的资源信息,首先发起一个IO操作请求,资源可用时,应用层注册的回调函数会被主动调用。但是异步通知不能直接调用应用层注册的回调函数,而是由驱动程序向应用层发送一个信号

信号含义


信号名含义默认操作
SIGHUP该信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控制进程结束时,通知同一会话内的各个作业与控制终端不再关联。终止
SIGINT该信号在用户键入INTR字符(通常是Ctrl-C)时发出,终端驱动程序发送此信号并送到前台进程中的每一个进程。终止
SIGQUIT该信号和SIGINT类似,但由QUIT字符(通常是Ctrl-\)来控制。终止
SIGILL该信号在一个进程企图执行一条非法指令时(可执行文件本身出现错误,或者试图执行数据段、堆栈溢出时)发出。终止
SIGFPE该信号在发生致命的算术运算错误时发出。这里不仅包括浮点运算错误,还包括溢出及除数为0等其它所有的算术的错误。终止
SIGKILL该信号用来立即结束程序的运行,并且不能被阻塞、处理和忽略。终止
SIGALRM该信号当一个定时器到时的时候发出。终止
SIGSTOP该信号用于暂停一个进程,且不能被阻塞、处理或忽略。暂停进程
SIGTSTP该信号用于暂停交互进程,用户可键入SUSP字符(通常是Ctrl-Z)发出这个信号。暂停进程
SIGCHLD子进程改变状态时,父进程会收到这个信号忽略
SIGABORT该信号用于结束进程终止

当应用层接收到一个信号时,可以对信号执行忽略、捕捉和缺省三种操作:

忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILLSIGSTOP

捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。

缺省信号:执行Linux对该信号的默认操作

应用层使用信号


以下是应用层捕捉SIGIO信号的简单示例:

void input_handler(int signum)
{//如果驱动发送了SIGIO信号,在此处理printf("recive from %d\n",signum);}
int main()
{int fd ,oflags;fd=open("/dev/global",O_RDWR,S_IRUSR | S_IWUSR);if(fd != -1)
{//启动信号机制signal(SIGIO,input_handler);//设置SIGIO信号的处理函数fcntl(fd,F_SETOWN,getpid());//将进程ID赋值给filp->f_owneroflags = fcntl(fd,F_GETFL);fcntl(fd,F_SETFL,oflags | FASYNC);//驱动的fasync方法被调用while(1){sleep(1000);}
}
}
  • 当应用层F_SETOWN, 驱动什么都没做,内核只是将进程的ID赋值给 filp->f_owner
  • 当应用层F_SETFL 被执行来打开 FASYNC, 驱动fasync 方法被调用.
  • 当数据到达, 驱动向进程发出一个 SIGIO 信号

驱动如何实现异步信号


驱动的实现主要用到一个结构体两个函数

fasync_struct结构体:

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标志变更

fasync_helper()函数是用来初始化fasync_struct结构体变量,并设置异步通知队列的

int fasync_helper(int fd, 	         	//文件描述符	struct file * filp, 		//文件指针int on, struct fasync_struct **fapp);   //要设置的结构

第三个参数on表示设置还是删除,on为真时初始化,为假时(0),移除.

kill_fasync():发送信号

void kill_fasync(struct fasync_struct **fp, int sig, int band)

fp:是已初始化的fasync_struct数据结构

sig:要发送的信号

band:在可读时设置为POLL_IN,在可写时设置为POLL_OUT;

驱动实例


static struct fasync_struct *btn_fasync;static irqreturn_t btn_irq_handler(int irq, void *dev)
{struct btn_t *p = (struct btn_t *)dev;//发送信号kill_fasync(&btn_fasync, SIGIO, POLL_IN);return IRQ_HANDLED;
}static int btn_drv_fasync(int fd, struct file *fp, int on)
{//初始化btn_fasync结构,并添加到异步通知列表中return fasync_helper(fd, fp, on, &btn_fasync);
}static int btn_drv_close(struct inode *inode, struct file *filp)
{if(filp->f_flags & FASYNC)fasync_helper(-1, flip, 0, &btn_fasync);//将文件从异步通知的列表中删除return 0;
}static struct file_operations btn_ops={.......release = btn_drv_close,.fasync = btn_drv_fasync,
};

主要步骤

1、构造struct fasync_struct链表的头

2、实现fasync接口函数,调用fasync_helper函数来构造struct fasync_struct节点,并加入链表。

3、在资源可用时,调用kill_fasync发送信号,并设置资源的可用类型是可读还是可写。

4、在文件最后一次关闭时,即在release接口中,需要显式调用驱动实现的fasync接口函数,将节点从链表中删除,这样进程就不会再次收到信号。

异步通知主要还是弄明白信号是软件层次对中断的一种模拟,并且信号是由驱动发出的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/79937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重新认识交叉编译

1. 我以前对交叉编译的认知 引用正点原子的话来讲就是: 说得对,但是不全面,直到最近项目中遇到了一个例子我才重新认识什么是交叉编译。 2. build/host/target的概念 参考: Cross-Compilation (automake) 参考: Specifying Target Triplets (Autocon…

Python二级 每周练习题18

练习一: 从键盘输入任意字符串,按照下面要求分离字符串中的字符: 1、分别取出该字符串的第偶数位的元素(提醒注意:是按照从左往右数的方式确定字符串的位置) 2、并依次存储到一个列表中; 3、输出这个列表。 答案: ninput(请输入任意字符串:) #创建变量n存放用户…

数据结构入门 — 树的概念与结构

本文属于数据结构专栏文章,适合数据结构入门者学习,涵盖数据结构基础的知识和内容体系,文章在介绍数据结构时会配合上动图演示,方便初学者在学习数据结构时理解和学习,了解数据结构系列专栏点击下方链接。 博客主页&am…

外包干了2个月,技术退步明显。。。。。

先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

【多线程】Thread 类 详解

Thread 类 详解 一. 创建线程1. 继承 Thread 类2. 实现 Runnable 接口3. 其他变形4. 多线程的优势-增加运行速度 二. Thread 类1. 构造方法2. 常见属性3. 启动线程-start()4. 中断线程-interrupt()5. 线程等待-join()6. 线程休眠-sleep()7. 获取当前线程引用 三. 线程的状态1. …

Buffer Pool

一.Buffer Pool的含义 Buffer Pool:缓冲池,简称BP,其作用是用来缓存表数据与索引数据,减少磁盘IO操作,提升效率。当Mysql执行查询的sql语句的时候,会先去缓存当中看是否有对应的数据,如果有则直…

显示器显示的画面突然偏红色如何解决

显示器显示的画面突然偏红色如何解决 1. 概述2. 解决方法结束语 1. 概述 显示器显示的画面突然偏红色 ,使用向日葵远程电脑,看到的画面是正常的,但是显示器上的画面确还是骗红的,这时候就需要看一下是不是开启了系统也夜间模式&a…

四川百幕晟科技:提升店铺质量方法是什么?

抖店是抖音旗下的移动电子商务平台,为商家提供在线销售和促销的机会。在抖店,经验值是商家评价和信誉的重要指标之一。反映了平台上商户的服务质量和用户满意度。那么,如何查看自己在抖店手机上的体验分数呢? 1、如何查看抖店手机…

Eclipse 安装串口终端工具

Eclipse已集成串口终端显示,只需要我们自己下载安装即可使用。使用SSH连接也差不多。 查看eclipse版本信息 help->About Eclipse 查看version,我的是4.7.3a,记住代号,我的是“Oxygen”,下面有用。 安装eclipse自带的“Termin…

FPGA实现Cordic算法——向量模式

FPGA实现Cordic算法——向量模式 FPGA实现Cordic算法——向量模式1.cordic算法基本原理2.FPGA实现cordic算法向量模式i、FPGA串行实现cordicii、FPGA流水线实现cordiciii、实验结果 FPGA实现Cordic算法——向量模式 1.cordic算法基本原理 FPGA中运算三角函数,浮点数…

初见QT,控件的基本应用,实现简单登录窗口

窗口实现代码 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//窗口设置this->setFixedSize(538, 373); //固定窗口大小this->setWindowIcon(QIcon("G:\\QT_Icon\\windos_icon2.png"))…

多图片展示弹窗插件

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>图片预览完善</title><style>/*** Created by WangCheng on 2020/9/24.*//*背景框*/.mask-layer * {padding: 0;margin: 0;box-sizing: border-box;}.mask-laye…

肖sir__mysql之三表__008

mysql之三表 create table student( stu_no int, stu_name varchar(10), sex char(1), age int(3), edit varchar(20) ) DEFAULT charsetutf8; insert into student values (1,‘wang’,‘男’,21,‘hello’), (2,‘小明’,‘女’,22,‘haha2’), (3,‘hu’,‘女’,23,‘haha3…

Fast-DDS 服务发现简要概述

阅读本文章需要对DDS基础概念有一些了解&#xff0c;一些内容来自Fast-DDS官方文档&#xff0c;一些是工作中踩过的坑。 1. 服务发现阶段 满足OMG标准的DDS服务发现分为两部分&#xff0c;分别是: PDP(Participant Discovery Protocol 参与者发现协议)&#xff1a;参与者确认…

豆瓣图书评分数据的可视化分析

导语 豆瓣是一个提供图书、电影、音乐等文化产品的社区平台&#xff0c;用户可以在上面发表自己的评价和评论&#xff0c;形成一个丰富的文化数据库。本文将介绍如何使用爬虫技术获取豆瓣图书的评分数据&#xff0c;并进行可视化分析&#xff0c;探索不同类型、不同年代、不同…

第13节-PhotoShop基础课程-裁剪工具

文章目录 前言1.裁剪工具1.基本操作 Alt Shift2.拉直3.内容识别 自动填充 2.透视裁剪工具3.切片工具-长图分成多个4.切片选择工具5. 存储为一张一张 前言 1.裁剪工具 1.基本操作 Alt Shift 2.拉直 可以矫正图片 3.内容识别 自动填充 2.透视裁剪工具 可以拉正图片 3.切片工具-…

Spring系列文章:Spring中的设计模式

一、简单⼯⼚模式 BeanFactory的getBean()⽅法&#xff0c;通过唯⼀标识来获取Bean对象。是典型的简单⼯⼚模式&#xff08;静态⼯⼚模 式&#xff09;&#xff1b; 二、⼯⼚⽅法模式 FactoryBean是典型的⼯⼚⽅法模式。在配置⽂件中通过factory-method属性来指定⼯⼚⽅法&a…

Python中进行特征重要性分析的9个常用方法

特征重要性分析用于了解每个特征(变量或输入)对于做出预测的有用性或价值。目标是确定对模型输出影响最大的最重要的特征&#xff0c;它是机器学习中经常使用的一种方法。 为什么特征重要性分析很重要? 如果有一个包含数十个甚至数百个特征的数据集&#xff0c;每个特征都可能…

发现某设备 adb shell ps 没有输出完整信息

某错误示例 并不是都使用 -ef 参数查找都能够返回完整信息&#xff0c;某些版本设备不适用 -ef 也不会返回完整信息。 简单兼容 简单兼容不同版本 Android 设备查找进程列表&#xff0c;没有通过脚本判断 Android 版本&#xff0c;如有兴趣可以自己修改。 :loop adb shell…

在测试过程中引入可观测性平台提升业务质量

作者 观测云 产品技术专家 成都办公室 - 刘跃兰 前言 随着微服务技术的发展&#xff0c;微服务概念已深入人心&#xff0c;越来越多的企业开始使用微服务架构来开发业务应用。业务应用系统的整体架构变得更加复杂&#xff0c;并存在各种各样的不确定性因素&#xff0c;从而对…