当前位置: 首页 > 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…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...