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

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②

  • 第十九章 驱动程序基石②
    • 19.3 异步通知
      • 19.3.1 适用场景
      • 19.3.2 使用流程
      • 19.3.3 驱动编程
      • 19.3.4 应用编程
      • 19.3.5 现场编程
      • 19.3.6 上机编程
      • 19.3.7 异步通知机制内核代码详解
    • 19.4 阻塞与非阻塞
      • 19.4.1 应用编程
      • 19.4.2 驱动编程
      • 19.4.3 驱动开发原则

第十九章 驱动程序基石②

在这里插入图片描述

19.3 异步通知

使用 GIT命令载后,本节源码位于这个目录下:

01_all_series_quickstart\ 
05_嵌入式 Linux驱动开发基础知识\source\ 
06_gpio_irq\ 05_read_key_irq_poll_fasync 

19.3.1 适用场景

在前面引入中断时,我们曾经举过一个例子:
在这里插入图片描述

妈妈怎么知道卧室里小孩醒了?
① 时不时进房间看一下:查询方式
简单,但是累
② 进去房间陪小孩一起睡觉,小孩醒了会吵醒她:休眠-唤醒
不累,但是妈妈干不了活了
③ 妈妈要干很多活,但是可以陪小孩睡一会,定个闹钟:poll方式 要浪费点时间,但是可以继续干活。
妈妈要么是被小孩吵醒,要么是被闹钟吵醒。
④ 妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈:异步通知 妈妈、小孩互不耽误
使用休眠-唤醒、POLL机制时,都需要休眠等待某个事件发生时,它们的差别在于后者可以指定休眠的时长。
在现实生活中:妈妈可以不陪小孩睡觉,小孩醒了之后可以主动通知妈妈。
如果 APP不想休眠怎么办?也有类似的方法:驱动程序有数据时主动通知APP,APP收到信号后执行信息处理函数。
什么叫“异步通知”?
你去买奶茶:
你在旁边等着,眼睛盯着店员,生怕别人插队,他一做好你就知道:你是主动等待他做好,这叫“同步”。 你付钱后就去玩手机了,店员做好后他会打电话告诉你:你是被动获得结果,这叫“异步”。

19.3.2 使用流程

驱动程序怎么通知 APP:发信号,这只有 3个字,却可以引发很多问题:
① 谁发:驱动程序发
② 发什么:信号
③ 发什么信号:SIGIO
④ 怎么发:内核里提供有函数
⑤ 发给谁:APP,APP要把自己告诉驱动
⑥ APP收到后做什么:执行信号处理函数
⑦ 信号处理函数和信号,之间怎么挂钩:APP注册信号处理函数
小孩通知妈妈的事情有很多:饿了、渴了、想找人玩。
Linux系统中也有很多信号,在 Linux内核源文件 include\uapi\asm-generic\signal.h中,有很多信号的宏定义:
在这里插入图片描述

就 APP而言,你想处理 SIGIO信息,那么需要提供信号处理函数,并且要跟 SIGIO挂钩。这可以通过一个 signal函数来“给某个信号注册处理函数”,用法如下:
在这里插入图片描述

APP还要做什么事?想想这几个问题:
① 内核里有那么多驱动,你想让哪一个驱动给你发 SIGIO信号?
APP要打开驱动程序的设备节点。
② 驱动程序怎么知道要发信号给你而不是别人?
APP要把自己的进程 ID告诉驱动程序。
③ APP有时候想收到信号,有时候又不想收到信号:
应该可以把 APP的意愿告诉驱动。
驱动程序要做什么?发信号。
① APP设置进程 ID时,驱动程序要记录下进程 ID;
② APP还要使能驱动程序的异步通知功能,驱动中有对应的函数:
APP打开驱动程序时,内核会创建对应的 file结构体,file中有 f_flags; f_flags中有一个 FASYNC位,它被设置为 1时表示使能异步通知功能。
当 f_flags中的 FASYNC位发生变化时,驱动程序的 fasync函数被调用。
③ 发生中断时,有数据时,驱动程序调用内核辅助函数发信号。
这个辅助函数名为 kill_fasync。
完美!
APP收到信号后,是怎么执行信号处理函数的?
这个,很难,有兴趣的话就看本节最后的文档。初学者没必要看。
综上所述,使用异步通知,也就是使用信号的流程如下图所示:
在这里插入图片描述

重点从②开始:
② APP给 SIGIO这个信号注册信号处理函数 func,以后 APP收到 SIGIO信号时,这个函数会被自动调用;
③ 把 APP的 PID(进程 ID)告诉驱动程序,这个调用不涉及驱动程序,在内核的文件系统层次记录 PID; ④ 读取驱动程序文件 Flag;
⑤ 设置 Flag里面的 FASYNC位为 1:当 FASYNC位发生变化时,会导致驱动程序的 fasync被调用;
⑥⑦ 调用 faync_helper,它会根据 FAYSNC的值决定是否设置 button_async->fa_file=驱动文件filp:
驱动文件 filp结构体里面含有之前设置的 PID。
⑧ APP可以做其他事;
⑨⑩ 按下按键,发生中断,驱动程序的中断服务程序被调用,里面调用 kill_fasync发信号;
⑪⑫⑬ APP收到信号后,它的信号处理函数被自动调用,可以在里面调用 read函数读取按键。

19.3.3 驱动编程

使用异步通知时,驱动程序的核心有 2:

① 提供对应的 drv_fasync函数; ② 并在合适的时机发信号。
drv_fasync函数很简单,调用 fasync_helper函数就可以,如下:

static struct fasync_struct *button_async; 
static int drv_fasync (int fd, struct file *filp, int on) 
{ return fasync_helper (fd, filp, on, &button_async); 
} 

fasync_helper函数会分配、构造一个 fasync_struct结构体 button_async:
① 驱动文件的 flag被设置为 FAYNC时:

button_async->fa_file = filp;  // filp表示驱动程序文件,里面含有之前设置的 PID ② 驱动文件被设置为非 FASYNC时: 
button_async->fa_file = NULL; 

以后想发送信号时,使用 button_async作为参数就可以,它里面“可能”含有 PID。
什么时候发信号呢?在本例中,在 GPIO中断服务程序中发信号。
怎么发信号呢?代码如下:

kill_fasync (&button_async, SIGIO, POLL_IN); 

第 1个参数:button_async->fa_file非空时,可以从中得到 PID,表示发给哪一个 APP; 第 2个参数表示发什么信号:SIGIO;
第 3个参数表示为什么发信号:POLL_IN,有数据可以读了。(APP用不到这个参数)

19.3.4 应用编程

应用程序要做的事情有这几件:
① 编写信号处理函数:

static void sig_func(int sig) 
{ int val; read(fd, &val, 4); printf("get button : 0x%x\n", val); } 

② 注册信号处理函数:

signal(SIGIO, sig_func); 

③ 打开驱动:

fd = open(argv[1], O_RDWR); 

④ 把进程 ID告诉驱动:

fcntl(fd, F_SETOWN, getpid()); 

⑤ 使能驱动的 FASYNC功能:

flags = fcntl(fd, F_GETFL); 
fcntl(fd, F_SETFL, flags | FASYNC); 

19.3.5 现场编程

19.3.6 上机编程

19.3.7 异步通知机制内核代码详解

还没写

19.4 阻塞与非阻塞

所谓阻塞,就是等待某件事情发生。比如调用 read读取按键时,如果没有按键数据则 read函数不会返回,它会让线程休眠等待。
使用 poll时,如果传入的超时时间不为 0,这种访问方法也是阻塞的。

使用 poll时,可以设置超时时间为 0,这样即使没有数据它也会立刻返回,这就是非阻塞方式。能不能让 read函数既能工作于阻塞方式,也可以工作于非阻塞方式?可以!
APP调用 open函数时,传入 O_NONBLOCK,就表示要使用非阻塞方式;默认是阻塞方式。
注意:对于普通文件、块设备文件,O_NONBLOCK不起作用。
注意:对于字符设备文件,O_NONBLOCK起作用的前提是驱动程序针对 O_NONBLOCK做了处理。
只能在 open时表明 O_NONBLOCK吗?在 open之后,也可以通过 fcntl修改为阻塞或非阻塞。
使用 GIT命令载后,本节源码位于这个目录下:

01_all_series_quickstart\ 
05_嵌入式 Linux驱动开发基础知识\source\ 
06_gpio_irq\ 06_read_key_irq_poll_fasync_block 

19.4.1 应用编程

open时设置:

int  fd = open(/dev/xxx”, O_RDWR | O_NONBLOCK);  /* 非阻塞方式 */ int  fd = open(/dev/xxx”, O_RDWR );  /* 阻塞方式 */ 

open之后设置:

int flags = fcntl(fd, F_GETFL); 
fcntl(fd, F_SETFL, flags | O_NONBLOCK);  /* 非阻塞方式 */ 
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);  /* 阻塞方式 */ 

19.4.2 驱动编程

以 drv_read为例:

static ssize_t drv_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK) return -EAGAIN; wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue)); …… 
} 

从驱动代码也可以看出来,当 APP打开某个驱动时,在内核中会有一个 struct file结构体对应这个驱动,这个结构体中有 f_flags,就是打开文件时的标记位;可以设置 f_flasgs的 O_NONBLOCK位,表示非阻塞;也可以清除这个位表示阻塞。
驱动程序要根据这个标记位决定事件未就绪时是休眠和还是立刻返回。

19.4.3 驱动开发原则

驱动程序程序“只提供功能,不提供策略”。就是说驱动程序可以提供休眠唤醒、查询等等各种方式,,驱动程序只提供这些能力,怎么用由 APP决定。

相关文章:

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石② 第十九章 驱动程序基石②19.3 异步通知19.3.1 适用场景19.3.2 使用流程19.3.3 驱动编程19.3.4 应用编程19.3.5 现场编程19.3.6 上机编程19.3.7 异步通知机制内核代码详解 19.4 阻塞与非阻塞19.4.1 应用编程19.4.2 驱动编程…...

trycatch、throw、throws

在Java中,try-catch、throw和throws是用于处理异常的重要关键字和机制,它们的作用如下: try-catch:try-catch 是用于捕获和处理异常的语句块。在try块中放置可能引发异常的代码。如果在try块中的代码引发了异常,控制流会跳转到与异常类型匹配的catch块。在catch块中,可以…...

问 ChatGPT 关于 GPT 的事情:数据准备篇

一、假如你是一名人工智能工程师,手里有一个65B的GPT大模型,但你需要一个6B左右的小模型,你会怎么做? 答:作为人工智能工程师,如果我手里有一个65B的GPT大模型,而我需要一个6B左右的小模型&…...

leetcode_17电话号码的组合

1. 题意 输出电话号码对应的字母左右组合 电话号码的组合 2. 题解 回溯 class Solution { public:void gen_res(vector<string> &res, vector<string> &s_m,string &digits, string &t, size_t depth) {if (depth digits.size()) {if ( !t.em…...

记录使用vue-test-utils + jest 在uniapp中进行单元测试

目录 前情安装依赖package.json配置jest配置测试文件目录编写setup.js编写第一个测试文件jest.fn()和jest.spyOn()jest 解析scss失败测试vuex$refs定时器测试函数调用n次手动调用生命周期处理其他模块导入的函数测试插槽 前情 uniapp推荐了测试方案dcloudio/uni-automator&…...

《C和指针》笔记30:函数声明数组参数、数组初始化方式和字符数组的初始化

文章目录 1. 函数声明数组参数2. 数组初始化方式2.1 静态初始化2.2 自动变量初始化 2.2 字符数组的初始化 1. 函数声明数组参数 下面两个函数原型是一样的&#xff1a; int strlen( char *string ); int strlen( char string[] );可以使用任何一种声明&#xff0c;但哪个“更…...

VBA技术资料MF64:遍历单元格搜索字符并高亮显示

【分享成果&#xff0c;随喜正能量】不要在乎他人的评论&#xff0c;不必理论与他人有关的是非&#xff0c;你只要做好自己就够了。苔花如米小&#xff0c;也学牡丹开。无论什么时候&#xff0c;都要有忠于自己的勇气&#xff0c;去做喜欢的事&#xff0c;去认识喜欢的人&#…...

一键智能视频编辑与视频修复算法——ProPainter源码解析与部署

前言 视频编辑和修复确实是随着电子产品的普及变得越来越重要的技能。有许多视频编辑工具可以帮助人们轻松完成这些任务如&#xff1a;Adobe Premiere Pro&#xff0c;Final Cut Pro X&#xff0c;Davinci Resolve&#xff0c;HitFilm Express&#xff0c;它们都提供一些视频修…...

Flutter开发环境的配置

2023-10最新版本 flutter SDK版本下载地址 https://flutter.cn/docs/development/tools/sdk/releases gradle各版本快速下载地址 https://blog.csdn.net/ii950606/article/details/109105402 JAVA SDK下载地址 https://www.oracle.com/java/technologies/downloads/#java…...

【超详细】Wireshark教程----Wireshark 分析ICMP报文数据试验

一&#xff0c;试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机&#xff08;虚拟机&#xff09; kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置&#xff1a; 编辑-------- 虚拟网路编辑器 更改设置进来以后 &#xff0c;先选择N…...

Linux命令(92)之rm

linux命令之rm 1.rm介绍 linux命令rm是用来删除一个或多个文件/目录&#xff0c;由于其删除的不可逆性&#xff0c;建议在日常工作中一定要慎用 2.rm用法 rm [参数] 文件/目录 rm常用参数 参数说明-r递归删除文件或目录-f不提示强制删除-i删除文件或目录前进行确认-v详细显…...

Mysql主从复制数据架构全面解读

大家好&#xff0c;我是山子&#xff0c;今天给大家分析Mysql 实现主从复制的方方面面&#xff0c;主从复制当然也是我们做读写分离的前提&#xff0c;以下内容是从各网络平台摘录整理总结归纳在一起的&#xff1b;内容已经从主从复制的各方面的维度进行了阐述&#xff1b;非常…...

ios证书类型及其作用说明

ios证书类型及其作用说明 很多刚开始接触iOS证书的开发者可能不是很了解iOS证书的类型功能和概念。下面对iOS证书的几个方面进行介绍。 apple开发账号分类&#xff1a; 免费账号&#xff1a; 无需支付费用给apple&#xff0c;使用个人信息注册的账号 可以开发测试安装&…...

警告-Ubuntu提示W: Possible missing firmware xxx解决方法

目录 现象原因解决方法 现象 当执行 sudo apt-get update或者sudo apt-get dist-upgrade时&#xff0c;有如下警告&#xff1a; W: Possible missing firmware /lib/firmware/rtl_nic/rtl8125a-3.fw for module r8169 W: Possible missing firmware /lib/firmware/rtl_nic/rt…...

有时候,使用 clang -g test.c 编译出可执行文件后,发现 gdb a.out 进行调试无法读取符号信息,为什么?

经过测试&#xff0c;gdb 并不是和所有版本的 llvm/clang 都兼容的 当 gdb 版本为 9.2 时&#xff0c;能支持 9.0.1-12 版本的 clang&#xff0c;但无法支持 16.0.6 版本的 clang 可以尝试使用 LLVM 专用的调试器 lldb 我尝试使用了 16.0.6 版本的 lldb 调试 16.0.6 的 clan…...

UG\NX二次开发 信息窗口的一些操作 NXOpen/ListingWindow

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG\NX二次开发 信息窗口的一些操作 NXOpen/ListingWindow 效果: 代码: #include "me.hpp" #include <NXOpen/ListingWindow.hxx> #include <…...

macbook电脑磁盘满了怎么删东西?

macbook是苹果公司的一款高性能笔记本电脑&#xff0c;受到很多用户的喜爱。但是&#xff0c;如果macbook的磁盘空间不足&#xff0c;可能会导致一些问题&#xff0c;比如无法开机、运行缓慢、应用崩溃等。那么&#xff0c;macbook磁盘满了无法开机怎么办&#xff0c;macbook磁…...

解释 RESTful API,以及如何使用它构建 web 应用程序

RESTful API是一种基于HTTP协议&#xff0c;使用REST架构风格设计的API。其核心思想是将所有的Web应用程序资源抽象为一组资源集合&#xff0c;并通过HTTP协议中的GET、POST、PUT、DELETE等几个方法对这些资源进行操作&#xff0c;使得Web应用程序能够方便地、高效地进行管理和…...

qml使用c++自定义listmodel数据

qml要使用c中自定义的model&#xff0c;首先该model类需要继承QAbstractListModel类&#xff0c;然后需要重写其中的三个函数&#xff0c;分别是 int rowCount(const QModelIndex &parent); QVariant data(const QModelIndex &index, int role Qt::DisplayRole); QHas…...

cf 解题报告 01

E. Power of Points Problem - 1857E - Codeforces 题意&#xff1a; 给你 n n n 个点&#xff0c;其整数坐标为 x 1 , … x n x_1,\dots x_n x1​,…xn​&#xff0c;它们位于一条数线上。 对于某个整数 s s s&#xff0c;我们构建线段[ s , x 1 s,x_1 s,x1​], [ s , x…...

SDXL 1.0电影级绘图工坊:Python入门教程与基础图像处理

SDXL 1.0电影级绘图工坊&#xff1a;Python入门教程与基础图像处理 1. 引言 你是不是也曾经被那些精美的AI生成图片所吸引&#xff0c;想要自己动手创作却不知道从何开始&#xff1f;今天我们就来聊聊如何用Python快速上手SDXL 1.0这个强大的AI绘图工具。 SDXL 1.0是当前最先…...

告别复杂配置!Qwen-Image-2512-SDNQ一键部署,打造专属AI绘画网站

告别复杂配置&#xff01;Qwen-Image-2512-SDNQ一键部署&#xff0c;打造专属AI绘画网站 1. 为什么选择Qwen-Image-2512-SDNQ镜像&#xff1f; 在AI绘画领域&#xff0c;模型部署往往意味着复杂的配置和环境搭建。Qwen-Image-2512-SDNQ-uint4-svd-r32镜像彻底改变了这一现状&…...

逆向新手也能懂:用Python脚本5分钟搞定‘长城杯’EasyRe逆向题

逆向工程零基础入门&#xff1a;用Python五分钟破解CTF异或加密题 第一次接触CTF逆向题时&#xff0c;看着满屏的汇编代码和反编译结果&#xff0c;我完全不知所措。直到发现有些题目其实只需要一点Python脚本就能解决——比如这道来自"长城杯"网络安全大赛的EasyRe题…...

【2025最新】基于SpringBoot+Vue的疫情隔离酒店管理系统管理系统源码+MyBatis+MySQL

系统架构设计### 摘要 近年来&#xff0c;全球范围内突发公共卫生事件频发&#xff0c;疫情隔离酒店作为防控体系的重要环节&#xff0c;其管理效率直接关系到公共卫生安全和社会稳定。传统酒店管理模式在应对大规模隔离需求时暴露出信息滞后、资源调配低效、数据孤岛等问题&am…...

阿里图标库(Iconfont)的本地引入 详细步骤

阿里图标库&#xff08;Iconfont&#xff09;本地引入 Vue3 详细步骤&#xff08;文字版&#xff09; 一、准备工作 登录 Iconfont 官网 访问 Iconfont 官网&#xff0c;使用账号登录&#xff08;若无账号需注册&#xff09;。 选择图标并加入项目 在搜索框输入关键词&#x…...

Neeshck-Z-lmage_LYX_v2实际作品:基于LoRA微调的专属IP形象批量生成

Neeshck-Z-lmage_LYX_v2实际作品&#xff1a;基于LoRA微调的专属IP形象批量生成 1. 引言&#xff1a;从零到一&#xff0c;打造你的专属数字形象 想象一下&#xff0c;你需要为你的品牌、游戏或者社交媒体账号设计一套统一的视觉形象。传统的做法是找设计师&#xff0c;沟通需…...

【agent原理】OpenClaw之agent全链路详解

未来已来,只需一句指令,养龙虾专栏导航,持续更新ing… openclaw的术语约定 专业术语 类比 核心作用 不用的后果 Agent Bootstrapping AI员工的入职仪式 给AI办工牌、定岗位职责、录用户信息、建工作文件夹,只执行一次 手动建文件格式错乱、agent读不到规则、配置不统一、重…...

东北老牌央国企陪跑机构哪家实力强

在东北地区&#xff0c;众多求职者&#xff0c;特别是应届毕业生&#xff0c;将目光投向了工作稳定、发展前景广阔的央国企。在这一背景下&#xff0c;专业的求职服务机构应运而生&#xff0c;为求职者提供系统化的支持。辽宁优泰教育咨询有限公司便是其中一家专注于该领域的服…...

Mojo+Python混合部署案例深度拆解(从Jupyter到生产环境的无缝迁移全路径)

第一章&#xff1a;MojoPython混合部署案例深度拆解&#xff08;从Jupyter到生产环境的无缝迁移全路径&#xff09;Mojo 作为新兴的系统级编程语言&#xff0c;与 Python 生态天然兼容&#xff0c;为机器学习模型从探索性开发&#xff08;Jupyter Notebook&#xff09;迈向高吞…...

Linux initramfs深度解析: 从内核启动到根文件系统的桥梁(3)

接前一篇文章&#xff1a;Linux initramfs深度解析: 从内核启动到根文件系统的桥梁&#xff08;2&#xff09; 设计思想与架构 1. 为什么需要initramfs 在initramfs出现之前&#xff0c;系统启动有一个根本性的问题&#xff1a;内核需要访问根文件系统来加载驱动程序&#xf…...