当前位置: 首页 > news >正文

Linux学习第26天:异步通知驱动开发: 主动

Linux版本号4.1.15   芯片I.MX6ULL                                    大叔学Linux    品人间百味  思文短情长 


       在正式开启今天的学习前,讲一讲为什么标题中加入了【主动】俩字。之前学习的阻塞和非阻塞IO,都是在被动的接受应用程序的操作。而今天的学习的异步通知则是驱动程序自动的去上报自己的状态,类似于以前我们学习的中断机制。

        谈到【主动】,和大家共勉一句话:凡事先干起来,就能消除90%的焦虑。当我第一次看到这句话的时候,突然有种豁然开朗的感觉。往往大家都是在托腮忧虑自己想象中的困难而久久不知所措而停止行动。殊不知,我们自己想象中的大部分困难也只存在于我们的想象中。当着手开始行动时,你会发现,也许并不难。

        本篇笔记主要学习了嵌入式Linux异步通知驱动开发相关知识,主要内容包括异步通知的相关概念及驱动开发的过程。其中异步通知又包括异步通知简介、驱动中的信号处理以及应用程序对异步通知的处理。驱动开发包括设备树的修改、驱动开发及测试。其中驱动开发是本节重点需要关注的内容。

        本篇笔记的思维导图如下:

f2792c8a4df940519a8bdd74963786e1.png

一、异步通知

        关键字:主动 中断

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); /* 开启当前进程异步通知功能 */

二、硬件原理图分析

9374cca617854814bce2c5c04ed16a3c.png

三、应用程序编写

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 品人间百味 思文短情长 在正式开启今天的学习前&#xff0c;讲一讲为什么标题中加入了【主动】俩字。之前学习的阻塞和非阻塞IO&#xff0c;都是在被动的接受应用程序的操作。而今天的学…...

SpringBoot的核心配置:YAML概述、基础语法;JSR303数据校验;多环境切换

SpringBoot核心配置 SpringBoot配置文件分类 SpringBoot是基于约定的&#xff0c;所以很多配置都有默认值&#xff0c;但如果想使用自己的配置替换默认配置的话&#xff0c;就可以使用 application.properties或者application.yml&#xff08;application.yaml&#xff09;进…...

把Qt6.2.4内置的标签打印了一遍

2023年10月31日&#xff0c;周二晚上 #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 表单校验的规则如下&#xff1a; <属性名>: [{ required: true,// 是否必填&#xff08;若有label则在其左上角显示红点&#xff0c;否则不显示必…...

搭建高性能分布式存储-minio

文章目录 搭建高性能分布式存储-minioDocker搭建minio&#xff08;单机部署纠删码模式&#xff09;⭐创建minio的bucket&#xff08;桶&#xff09;⭐SpringBootminio项目实战 ⭐1&#xff1a;导入minio的maven依赖2&#xff1a;编写MinioProperties.class3&#xff1a;applica…...

leetCode 137. 只出现一次的数字 II(拓展篇) + 模5加法器 + 真值表(数字电路)

leetCode 137. 只出现一次的数字 II 题解可看我的往期文章 leetCode 137. 只出现一次的数字 II 位运算 模3加法器 真值表&#xff08;数字电路&#xff09; 有限状态机-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/134138112?spm1001.2014.3001.5501…...

docker导致root空间满进入不了系统解决方案

由于docker建立镜像会产生很多缓存文件&#xff0c;最终导致root目录满&#xff0c;进入不了系统 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版本&#xff1a;1.13.6 1. 问题 flink 任务运行在yarn集群,plugins加载失效,导致通过扩展资源获取任务参数失效 2. 问题定位 yarn容器的jar包及插件信息,jar包是正常上传 源码定位 加载plugins入口&#xff0c;TaskMana…...

显卡服务器的特点和优势在哪里

随着科技的发展以及人们对于计算机性能的需求提高&#xff0c;显卡服务器是主要使用图形处理器进行计算和运算&#xff0c;拥有更加强大的计算能力&#xff0c;今天小编就来给大家讲一讲显卡服务器的特点和优势是什么&#xff01; 1.高可靠性&#xff1a;显卡服务器采用高品质的…...

c++设计模式二:原型模式

使用场景&#xff1a;当需要构建多个相同的类对象时&#xff0c;而且该类对象结构较为复杂&#xff0c;如果每个都重新组织构建会很麻烦。 其实&#xff0c;就是写一个拷贝构造函数&#xff0c;或者写一个拷贝每个成员变量的clone()方法。 举例说明&#xff1a;比如一个相亲网站…...

【Qt控件之QMessageBox】详解

Qt控件之QMessageBox 描述基于属性的API富文本和文本格式属性严重程度以及图标和Pixmap属性静态函数API 高级用法默认按钮和退出按钮示例使用场景 描述 QMessageBox类提供了一个模态对话框&#xff0c;用于通知用户或向用户提问并接收答案。 消息框显示一个主要文本以提醒用户…...

SSH安全登录远程主机

SSH服务器简介 SSH即Security SHell的意思&#xff0c;它可以将连线的封包进行加密技术&#xff0c;之后进行传输&#xff0c;因此相当的安全。 SSH是一种协议标准&#xff0c;其目的是实现安全远程登录以及其它安全网络服务。 SSH协定&#xff0c;在预设的状态下&#xff0c;…...

揭秘!产品经理提升效率的秘密武器:10款AI生成PPT工具

AI的爆炸式增长表现令人惊艳&#xff0c;现有的各类AI工具正在重塑各行各业&#xff0c;不同程度地提高人们的工作效率&#xff0c;并有望创造新的职业机会。但是&#xff0c;面对市面上数量众多的AI工具&#xff0c;且每周都会蹦出新的产品&#xff0c;即便是以好奇心富称的产…...

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接口都是用于在网络上进行通信和数据交换的技术&#xff0c;但它们在设计和使用上有一些重要的区别和相似之处。 相同点&#xff1a; 基于HTTP协议&#xff1a;无论是WebService还是RESTful接口&#xff0c;它们都是通过HTTP协议进行通信的。 支持多种数据…...

jenkins自动化操作步骤(gitblit)

1、登陆地址&#xff1a; http://xxxxxxxxx.org:xxxx/ admin/xxxx 2、创建任务 选择构建一个maven项目 3、配置 最多只保留一天一个任务 选择git仓库和账号密码 选择代码对应分支 build项&#xff1a; 1&#xff09;使用父项目的pom文件&#xff1a;k56-boot/pom.xml 2&…...

centos中mongodb设置服务自启动并 允许远程IP访问

安装mongodb参考 注意的是配置文件需要把journal设置为true 制作为系统服务 创建MongoDB服务文件。运行以下命令创建服务文件/etc/systemd/system/mongod.service&#xff1a; vi /etc/systemd/system/mongod.service [Unit] DescriptionMongoDB Database Server Documenta…...

实时定位和配送追踪:开发万岳同城外卖APP的关键技术特性

随着生活节奏的不断加快&#xff0c;外卖服务已经成为许多人日常生活中不可或缺的一部分。无论是工作日的午餐&#xff0c;还是周末的家庭聚会&#xff0c;外卖APP已经成为满足各种美食需求的首选方式。然而&#xff0c;同城外卖APP的成功不仅仅取决于美味的食物选择&#xff0…...

数据库强化(3.存储过程)

1.什么是存储过程&#xff1f; 存储过程&#xff08;Stored Procedure&#xff09;是一种在数据库中存储复杂程序&#xff0c;以便外部程序调用的一种数据库对象。MySQL 5.0 版本开始支持存储过程。 它是为了完成特定功能的SQL语句集&#xff0c;经编译创建并保存在数据库中&a…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...