Linux学习第26天:异步通知驱动开发: 主动
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长
在正式开启今天的学习前,讲一讲为什么标题中加入了【主动】俩字。之前学习的阻塞和非阻塞IO,都是在被动的接受应用程序的操作。而今天的学习的异步通知则是驱动程序自动的去上报自己的状态,类似于以前我们学习的中断机制。
谈到【主动】,和大家共勉一句话:凡事先干起来,就能消除90%的焦虑。当我第一次看到这句话的时候,突然有种豁然开朗的感觉。往往大家都是在托腮忧虑自己想象中的困难而久久不知所措而停止行动。殊不知,我们自己想象中的大部分困难也只存在于我们的想象中。当着手开始行动时,你会发现,也许并不难。
本篇笔记主要学习了嵌入式Linux异步通知驱动开发相关知识,主要内容包括异步通知的相关概念及驱动开发的过程。其中异步通知又包括异步通知简介、驱动中的信号处理以及应用程序对异步通知的处理。驱动开发包括设备树的修改、驱动开发及测试。其中驱动开发是本节重点需要关注的内容。
本篇笔记的思维导图如下:

一、异步通知
关键字:主动 中断
1.异步通知简介
关键字:信号
在应用程序中使用 signal 函数来设置指定信号的处理函数.
sighandler_t signal(int signum, sighandler_t handler)
signum:要设置处理函数的信号。
handler: 信号的处理函数。
返回值: 设置成功的话返回信号的前一个处理函数,设置失败的话返回 SIG_ERR。
2.驱动中的信号处理
1)、fasync_struct
struct fasync_struct {
spinlock_t fa_lock;
int magic;
int fa_fd;
struct fasync_struct *fa_next;
struct file *fa_file;
struct rcu_head fa_rcu;
};
一般将 fasync_struct 结构体指针变量定义到设备结构体中。
2)、fasync函数
int (*fasync) (int fd, struct file *filp, int on)
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
当应用程序通过“fcntl(fd, F_SETFL, flags | FASYNC)”改变fasync 标记的时候,驱动程序 file_operations 操作集中的 fasync 函数就会执行。
在关闭驱动文件的时候需要在 file_operations 操作集中的 release 函数中释放 fasync_struct,fasync_struct 的释放函数同样为 fasync_helper。
3)、kill_fasync
负责发送指定的信号。函数的原型如下:
void kill_fasync(struct fasync_struct **fp, int sig, int band)
fp:要操作的 fasync_struct。
sig: 要发送的信号。
band: 可读时设置为 POLL_IN,可写时设置为 POLL_OUT。
3.应用程序对异步通知的处理
1)、注册信号处理函数
2)、将本应用程序的进程号告诉给内核
fcntl(fd, F_SETOWN, getpid())
3)、开启异步通知
flags = fcntl(fd, F_GETFL); /* 获取当前的进程状态 */
fcntl(fd, F_SETFL, flags | FASYNC); /* 开启当前进程异步通知功能 */
二、硬件原理图分析

三、应用程序编写
1.修改设备树文件
2.程序编写
#include <linux/fcntl.h>//因为要用到相关的 API 函数。
struct fasync_struct *async_queue; /* 设备结构体中加入异步相关结构体 */
109 if(atomic_read(&dev->releasekey)) { /* 一次完整的按键过程 */
110 if(dev->async_queue)
111 kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
112 }
如果是一次完整的按键过程,那么就通过 kill_fasync 函数发送 SIGIO 信号。
269 static int imx6uirq_fasync(int fd, struct file *filp, int on)
270 {
271 struct imx6uirq_dev *dev = (struct imx6uirq_dev *)
filp->private_data;
272 return fasync_helper(fd, filp, on, &dev->async_queue);
273 }
imx6uirq_fasync 函数,为 file_operations 操作集中的 fasync 函数,此函数内容很简单,就是调用一下 fasync_helper。
281 static int imx6uirq_release(struct inode *inode, struct file *filp)
282 {
283 return imx6uirq_fasync(-1, filp, 0);
284 }
release 函数,应用程序调用 close 函数关闭驱动设备文件的时候此函数就会执行,在此函数中释放掉 fasync_struct 指针变量。
292 .fasync = imx6uirq_fasync,
293 .release = imx6uirq_release,
设置 file_operations 操作集中的 fasync 和 release 这两个成员变量。
3.编写测试APP
27 /*
28 * SIGIO 信号处理函数
29 * @param - signum : 信号值
30 * @return : 无
31 */
32 static void sigio_signal_func(int signum)
33 {
34 int err = 0;
35 unsigned int keyvalue = 0;
36
37 err = read(fd, &keyvalue, sizeof(keyvalue));
38 if(err < 0) {
39 /* 读取错误 */
40 } else {
41 printf("sigio signal! key value=%d\r\n", keyvalue);
42 }
43 }
sigio_signal_func 函数, SIGIO 信号的处理函数,当驱动程序有效按键按下以后就会发送 SIGIO 信号,此函数就会执行。此函数通过 read 函数读取按键值,然后通过printf 函数打印在终端上。
signal(SIGIO, sigio_signal_func);
通过 signal 函数设置 SIGIO 信号的处理函数为 sigio_signal_func。
71 fcntl(fd, F_SETOWN, getpid()); /* 将当前进程的进程号告诉给内核 */
72 flags = fcntl(fd, F_GETFD); /* 获取当前的进程状态 */
73 fcntl(fd, F_SETFL, flags | FASYNC);/* 设置进程启用异步通知功能 */
设置当前进程的状态,开启异步通知的功能。
四、运行测试
1.编译驱动程序和测试APP
1)、编译驱动程序
obj-m := asyncnoti.o
make -j32 asyncnoti.ko”的驱动模块
2)、编译测试APP
arm-linux-gnueabihf-gcc asyncnotiApp.c -o asyncnotiApp
应用程序asyncnotiApp
2.运行测试
depmod //第一次加载驱动的时候需要运行此命令
modprobe asyncnoti.ko //加载驱动
./asyncnotiApp /dev/asyncnoti
按下开发板上的 KEY0 键,终端就会输出按键值。
五、总结
本篇笔记主要学习了嵌入式Linux异步通知驱动开发相关知识,主要内容包括异步通知的相关概念及驱动开发的过程。
本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。
相关文章:
Linux学习第26天:异步通知驱动开发: 主动
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 在正式开启今天的学习前,讲一讲为什么标题中加入了【主动】俩字。之前学习的阻塞和非阻塞IO,都是在被动的接受应用程序的操作。而今天的学…...
SpringBoot的核心配置:YAML概述、基础语法;JSR303数据校验;多环境切换
SpringBoot核心配置 SpringBoot配置文件分类 SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用 application.properties或者application.yml(application.yaml)进…...
把Qt6.2.4内置的标签打印了一遍
2023年10月31日,周二晚上 #include <QGridLayout> #include <QPushButton> #include <QLabel> #include <QApplication> #include <QStyle>int main(int argc, char *argv[]) {QApplication a(argc, argv);QWidget widget;widget.set…...
element-ui 表单校验・大全
目录 1、对全部表单项的校验2、校验指定字段3、自定义函数校验表单4、一行内多个输入框的校验 element-ui 官网 element-ui 表单校验的规则如下: <属性名>: [{ required: true,// 是否必填(若有label则在其左上角显示红点,否则不显示必…...
搭建高性能分布式存储-minio
文章目录 搭建高性能分布式存储-minioDocker搭建minio(单机部署纠删码模式)⭐创建minio的bucket(桶)⭐SpringBootminio项目实战 ⭐1:导入minio的maven依赖2:编写MinioProperties.class3:applica…...
leetCode 137. 只出现一次的数字 II(拓展篇) + 模5加法器 + 真值表(数字电路)
leetCode 137. 只出现一次的数字 II 题解可看我的往期文章 leetCode 137. 只出现一次的数字 II 位运算 模3加法器 真值表(数字电路) 有限状态机-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/134138112?spm1001.2014.3001.5501…...
docker导致root空间满进入不了系统解决方案
由于docker建立镜像会产生很多缓存文件,最终导致root目录满,进入不了系统 df -h docker默认路径是在/var/lib/docker下 可以通过命令查看docker占用空间 docker system df 如果占用空间太大 可用以下命令清理 $ docker image prune -h Flag shorth…...
uni-app遮罩遮住小程序tabbar
uni-app遮罩遮住小程序tabbar 1、用uni-app自带的方法显示隐藏 //通过弹窗显隐控制导航栏的显示和隐藏 const popupChange e >{if(e.show){//隐藏tabbaruni.hideTabBar()}else{//显示tabbaruni.showTabBar()}state.searchIcon e.show } //通过弹窗显隐控制导航栏的显示和…...
Flink on yarn 加载失败plugins失效问题解决
Flink on yarn 加载失败plugins失效问题解决 flink版本:1.13.6 1. 问题 flink 任务运行在yarn集群,plugins加载失效,导致通过扩展资源获取任务参数失效 2. 问题定位 yarn容器的jar包及插件信息,jar包是正常上传 源码定位 加载plugins入口,TaskMana…...
显卡服务器的特点和优势在哪里
随着科技的发展以及人们对于计算机性能的需求提高,显卡服务器是主要使用图形处理器进行计算和运算,拥有更加强大的计算能力,今天小编就来给大家讲一讲显卡服务器的特点和优势是什么! 1.高可靠性:显卡服务器采用高品质的…...
c++设计模式二:原型模式
使用场景:当需要构建多个相同的类对象时,而且该类对象结构较为复杂,如果每个都重新组织构建会很麻烦。 其实,就是写一个拷贝构造函数,或者写一个拷贝每个成员变量的clone()方法。 举例说明:比如一个相亲网站…...
【Qt控件之QMessageBox】详解
Qt控件之QMessageBox 描述基于属性的API富文本和文本格式属性严重程度以及图标和Pixmap属性静态函数API 高级用法默认按钮和退出按钮示例使用场景 描述 QMessageBox类提供了一个模态对话框,用于通知用户或向用户提问并接收答案。 消息框显示一个主要文本以提醒用户…...
SSH安全登录远程主机
SSH服务器简介 SSH即Security SHell的意思,它可以将连线的封包进行加密技术,之后进行传输,因此相当的安全。 SSH是一种协议标准,其目的是实现安全远程登录以及其它安全网络服务。 SSH协定,在预设的状态下,…...
揭秘!产品经理提升效率的秘密武器:10款AI生成PPT工具
AI的爆炸式增长表现令人惊艳,现有的各类AI工具正在重塑各行各业,不同程度地提高人们的工作效率,并有望创造新的职业机会。但是,面对市面上数量众多的AI工具,且每周都会蹦出新的产品,即便是以好奇心富称的产…...
Oracle修改带数据的字段类型
insert into TNW_FUND_SELORG(TFDINFOID,TSOINFOID) select TFD_INFO_ID,TSO_INFO_ID from TFD_SEL_FUNDLINK_TO_OLDFUNDWEB_DB /*修改原字段名*/ ALTER TABLE 表名 RENAME COLUMN 字段名 TO 字段名1; /*添加一个和原字段同名的字段*/ ALTER TABLE 表名 ADD 字段名 VARCHAR…...
WebService接口方式和Restful接口这两者有什么区别和相同点
WebService和RESTful接口都是用于在网络上进行通信和数据交换的技术,但它们在设计和使用上有一些重要的区别和相似之处。 相同点: 基于HTTP协议:无论是WebService还是RESTful接口,它们都是通过HTTP协议进行通信的。 支持多种数据…...
jenkins自动化操作步骤(gitblit)
1、登陆地址: http://xxxxxxxxx.org:xxxx/ admin/xxxx 2、创建任务 选择构建一个maven项目 3、配置 最多只保留一天一个任务 选择git仓库和账号密码 选择代码对应分支 build项: 1)使用父项目的pom文件:k56-boot/pom.xml 2&…...
centos中mongodb设置服务自启动并 允许远程IP访问
安装mongodb参考 注意的是配置文件需要把journal设置为true 制作为系统服务 创建MongoDB服务文件。运行以下命令创建服务文件/etc/systemd/system/mongod.service: vi /etc/systemd/system/mongod.service [Unit] DescriptionMongoDB Database Server Documenta…...
实时定位和配送追踪:开发万岳同城外卖APP的关键技术特性
随着生活节奏的不断加快,外卖服务已经成为许多人日常生活中不可或缺的一部分。无论是工作日的午餐,还是周末的家庭聚会,外卖APP已经成为满足各种美食需求的首选方式。然而,同城外卖APP的成功不仅仅取决于美味的食物选择࿰…...
数据库强化(3.存储过程)
1.什么是存储过程? 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。MySQL 5.0 版本开始支持存储过程。 它是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中&a…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
