Linux 驱动开发基础知识——APP 怎么读取按键值(十二)

 个人名片:

🦁作者简介:学生
🐯个人主页:妄北y

🐧个人QQ:2061314755

🐻个人邮箱:2061314755@qq.com
🦉个人WeChat:Vir2021GKBS
🐼本文由妄北y原创,首发CSDN🎊🎊🎊
🐨座右铭:大多数人想要改造这个世界,但却罕有人想改造自己。

专栏导航:

妄北y系列专栏导航:

C/C++的基础算法:C/C++是一种常用的编程语言,可以用于实现各种算法,这里我们对一些基础算法进行了详细的介绍与分享。🎇🎇🎇

QT基础入门学习:对QT的基础图形化页面设计进行了一个简单的学习与认识,利用QT的基础知识进行了翻金币小游戏的制作🤹🤹🤹

Linux基础编程:初步认识什么是Linux,为什么学Linux,安装环境,进行基础命令的学习,入门级的shell编程。🍻🍻🍻

Linux应用开发基础开发:分享Linux的基本概念、命令行操作、文件系统、用户和权限管理等,网络编程相关知识,TCP/IP 协议、套接字(Socket)编程等,可以实现网络通信功能。💐💐💐

Linux项目开发:Linux基础知识的实践,做项目是最锻炼能力的一个学习方法,这里我们会学习到一些简单基础的项目开发与应用,而且都是毕业设计级别的哦。🤸🤸🤸


非常期待和您一起在这个小小的互联网世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨ 

文章介绍:

🎉本篇文章对Linux驱动基础学习的相关知识进行分享!🥳🥳🥳

   在做单片机开发时,要读取 GPIO 按键,我们通常是执行一个循环,不断地检测 GPIO 引脚电平有没有发生变化。但是在 Linux 系统中,读取 GPIO 按键要考虑到效率,引入了很多种方法:查询方式(非阻塞)休眠-唤醒(阻塞方式)poll 方式异步通知方式

如果您觉得文章不错,期待你的一键三连哦,你的鼓励是我创作动力的源泉,让我们一起加油,一起奔跑,让我们顶峰相见!!!💪💪💪

🎁感谢大家点赞👍收藏⭐评论✍️

目录:

目录

一、APP 怎么读取按键值

1.1 驱动的基本技能:

1.2 APP 开发的基本技能:

二、妈妈怎么知道孩子醒了

2.1 时不时进房间看一下:查询方式

2.2 进去房间陪小孩一起睡觉,小孩醒了会吵醒她:休眠-唤醒

2.3 妈妈要干很多活,但是可以陪小孩睡一会,定个闹钟:poll 方式

2.4 妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈:异步通知

三、APP 读取按键的 4 种方法

3.1 查询方式

3.2 休眠-唤醒方式

3.3  poll 方式

3.4 异步通知方式 

3.4.1 异步通知的原理:发信号

3.4.2 应用程序之间发信号示例代码

 四、驱动程序提供能力,不提供策略


一、APP 怎么读取按键值

        在做单片机开发时,要读取 GPIO 按键,我们通常是执行一个循环,不断地检测 GPIO 引脚电平有没有发生变化。但是在 Linux 系统中,读取 GPIO 按键要考虑到效率,引入了很多种方法:查询方式(非阻塞)休眠-唤醒(阻塞方式)poll 方式异步通知方式。这 4 种方法并不仅仅用于 GPIO 按键,在所有的 APP 调用驱动程序过程中,都是使用这些方法。通过这 4 种方式的学习,我们可以掌握如下知识:

1.1 驱动的基本技能:

        中断、休眠、唤醒、poll 等机制。

        这些基本技能是驱动开发的基础,其他大型驱动复杂的地方是它的框架及设计思想,但是基本技术就这些。

1.2 APP 开发的基本技能:

        阻塞 、非阻塞、休眠、poll、异步通知

二、妈妈怎么知道孩子醒了

 妈妈怎么知道卧室里小孩醒了?

2.1 时不时进房间看一下:查询方式

        简单,但是累

2.2 进去房间陪小孩一起睡觉,小孩醒了会吵醒她:休眠-唤醒

        不累,但是妈妈干不了活了

2.3 妈妈要干很多活,但是可以陪小孩睡一会,定个闹钟:poll 方式

         要浪费点时间,但是可以继续干活。

         妈妈要么是被小孩吵醒,要么是被闹钟吵醒。

2.4 妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈:异步通知

        妈妈、小孩互不耽误

这 4 种方法没有优劣之分,在不同的场合使用不同的方法。

三、APP 读取按键的 4 种方法

APP 去读取按键和举例的场景很相似,也有 4 种方法:

查询方式                 休眠-唤醒方式                 poll 方式                 异步通知方式

2、3、4 种方法,都涉及中断服务程序。中断,就像小孩醒了会哭闹一样, 中断不经意间到来,它会做某些事情:唤醒 APP、向 APP 发信号

所以,在按键驱动程序中,中断是核心

        实际上,中断无论是在单片机还是在 Linux 中都很重要。在 Linux 中,中断的知识还涉及进程、线程等。 

写一个驱动程序的套路     

 

写一个驱动程序的套路   

3.1 查询方式

这种方法最简单:和之前的LED驱动程序类似,之前是写引脚来改变高低电平,现在我们是不断读取引脚来查询是否发生电平的变化

        驱动程序中构造、注册一个 file_operations 结构体,里面提供有对应的 open,read 函数。        

        APP 调用 open 时,导致驱动中对应的 open 函数被调用,在里面配置 GPIO 为输入引脚。

        APP 调用 read 时,导致驱动中对应的 read 函数被调用,它读取寄存器,把引脚状态直接返回给 APP。

3.2 休眠-唤醒方式

 驱动程序中构造、注册一个 file_operations 结构体,里面提供有对应的 open,read 函数

        APP 调用 open 时,导致驱动中对应的 open 函数被调用,在里面配置 GPIO 为输入引脚;并且注册 GPIO 的中断处理函数

        APP 调用 read 时,导致驱动中对应的 read 函数被调用,如果有按键数据则直接返回给 APP否则 APP 在内核态休眠

        当用户按下按键时,GPIO 中断被触发,导致驱动程序之前注册的中断服务程序被执行。它会记录按键数据,并唤醒休眠中的 APP

        APP 被唤醒后继续在内核态运行,即继续执行驱动代码,把按键数据返回给 APP(的用户空间)。

3.3  poll 方式

        上面的休眠-唤醒方式有个缺点:如果用户一直没操作按键,那么 APP 就会永远休眠。 我们可以给 APP 定个闹钟,这就是 poll 方式。

 驱动程序中构造、注册一个 file_operations 结构体,里面提供有对应的 open,read,poll 函数

        APP 调用 open 时,导致驱动中对应的 open 函数被调用,在里面配置 GPIO 为输入引脚;并且注册 GPIO 的中断处理函数。

        APP 调用 poll 或 select 函数,意图是“查询”是否有数据,这 2 个 函数都可以指定一个超时时间,即在这段时间内没有数据的话就返回错误。这会导致驱动中对应的 poll 函数被调用,如果有按键数据则直接返回给 APP;否则 APP 在内核态休眠一段时间

        当用户按下按键时,GPIO 中断被触发,导致驱动程序之前注册的中断服务程序被执行。它会记录按键数据,并唤醒休眠中的 APP。

        如果用户没按下按键,但是超时时间到了,内核也会唤醒 APP。

        所以 APP 被唤醒有 2 种原因用户操作了按键超时。被唤醒的 APP 在内核态继续运行,即继续执行驱动代码,把“状态”返回给 APP(的用户空间)。

        APP 得到 poll/select 函数的返回结果后,如果确认是有数据的,则再调用 read 函数,这会导致驱动中的 read 函数被调用,这时驱动程序中含有数据,会直接返回数据。

3.4 异步通知方式 

3.4.1 异步通知的原理:发信号

异步通知的实现原理是:内核给 APP 发信号。信号有很多种,这里发的是 SIGIO。 

驱动程序给应用程序发信号,应用程序收到信号后执行它的信号处理函数

驱动程序中构造、注册一个file_operations 结构体,里面提供有对应的 open,read,fasync函数。

◼ APP 调用 open 时,导致驱动中对应的 open 函数被调用,在里面配置 GPIO 为输入引脚;并且注册 GPIO 的中断处理函数

◼ APP 给信号 SIGIO 注册自己的处理函数:my_signal_fun

◼ APP 调用 fcntl 函数,把驱动程序的 flag 改为 FASYNC,这会导致驱动程序的 fasync 函数被调用,它只是简单记录进程 PID

◼ 当用户按下按键时,GPIO 中断被触发,导致驱动程序之前注册的中断服务程序被执行。它会记录按键数据,然后给进程 PID 发送 SIGIO 信号

◼ APP 收到信号后会被打断,先执行信号处理函数:在信号处理函数中可以去调用 read 函数读取按键值。

◼ 信号处理函数返回后,APP 会继续执行原先被打断的代码

3.4.2 应用程序之间发信号示例代码

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void my_sig_func(int signo)
{
    printf("get a signal : %d\n", signo);
}

int main(int argc, char **argv)
{
    int i = 0;
    
    signal(SIGIO, my_sig_func);        //事件处理函数,如果这里没有事件处理函数,则收到应用程序的信号就会停下退出,如果有事件处理函数,则收到应用程序后先执行事件处理函数再继续执行不会停止进程
    
    while (1) 
    {
        printf("Hello, world %d!\n", i++);    
        sleep(2);
    }
    
    return 0;
}


第 13 行注册信号处理函数

第 15 行就是一个无限循环。在它运行期间,你可以 用另一个 APP 发信号给它。 

$ gcc -o signal signal.c // 编译程序
$ ./signal & // 后台运行
$ ps -A | grep signal // 查看进程 ID,假设是 9527
$ kill -SIGIO 9527 // 给这个进程发信号
book@100ask:~/05_嵌入式Linux驱动开发基础知识/source/03_signal_example$ gcc -o signal signal.c
book@100ask:~/05_嵌入式Linux驱动开发基础知识/source/03_signal_example$ ./signal

 

重新开一个进程查询ID

book@100ask:~$ ps -A

book@100ask:~$ kill -SIGIO 4491

这样另一边的进程就收到信息了

 

 四、驱动程序提供能力,不提供策略

        我们的驱动程序可以实现上述 4 种提供按键的方法,但是驱动程序不应该限制 APP 使用哪种方法

        这就是驱动设计的一个原理:提供能力,不提供策略。就是说,你想用哪种方法都行,驱动程序都可以提供;但是驱动程序不能限制你使用哪种方法  。     

大佬觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥任务在无形中完成,价值在无形中升华,让我们一起加油吧!🌙🌙🌙

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Dasviewer时怎样让分屏且全屏状态下,模型能持续转动?

答&#xff1a;轻微甩动下就可以旋转了&#xff0c;此外直接拖入打开模型也可以旋转。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览…

STL常用之vector,list,stack,queue,deque总结与对比

一&#xff0c;vector 1&#xff09;底层 vector的底层是开辟出来的一块连续空间&#xff0c;类似于数组&#xff0c;每次空间满了之后会根据不同的编译器有不同的扩容倍数。 2&#xff09;优劣 优点&#xff1a;随机访问效率高&#xff0c;因为地址是连续的&#xff0c;底层…

接口测试总结及其用例设计方法

接口测试的总结文档 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xff1a;主要介绍为什…

【JavaEE】_synchronized关键字——监视器锁monitor lock

目录 1. synchronized的特性 2. synchronized的使用 3. Java标准库中的线程安全类 1. synchronized的特性 &#xff08;1&#xff09;互斥&#xff1a; 前文已经介绍&#xff0c;某个线程执行到某个对象的synchronized中时&#xff0c;其他线程如果也执行到同一个对象&…

卡在Installing CocoaPods dependencies (this may take a few minutes)这一步

卡在了Installing CocoaPods dependencies (this may take a few minutes)这一步怎么办 前置条件 注意一&#xff1a;请不要在目录、文件名中使用中文、空格等特殊符号。请不要单独使用常见的关键字作为项目名&#xff08;如 class, native, new, package 等等&#xff09;。请…

IP详细地理位置查询:技术原理与应用实践

IP地址是互联网上设备的唯一标识&#xff0c;在网络安全、个性化服务等领域具有重要意义。通过IP详细地理位置查询&#xff0c;可以获取到IP地址所在地的具体信息&#xff0c;为网络管理、定位服务等提供支持。IP数据云将深入探讨IP详细地理位置查询的技术原理、应用实践以及相…

Android Studio插件版本与Gradle 版本对应关系

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、Gradle各版本对应关系3.1 Gradle 版…

psm的stata实现

1. PSM 简介 在经济学中&#xff0c;我们通常希望评估某项公共政策实施后的效应&#xff0c;为此&#xff0c;我们构建 "处理组" 和 "控制组" 以评估「处理效应 (treatment effect)」。然而&#xff0c;我们的数据通常来自非随机的观察研究中&#xff0c;处…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时&#xff0c;亚马逊会将它们关联在一起&#xff0c;从而可能导致账号被封禁或限制。 为了避免这种情况&#xff0c;许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题&#xff1f; IP代理是…

光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表

光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表 文章目录 光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表前言一、可视化工具有哪些&#xff1f;二、那如何做出正确可视化图表 &#xff1f;GLAD原则1.G原则2.L原则3.A原则4.D原则 三、总结最后…

软件测试方法_边界值分析法

目录&#xff1a; ①边界值分析法的介绍和概念 ②边界值分析法的原理和思想 ③单缺陷假设和多缺陷假设 ④边界值测试数据类型 ⑤内部边界值分析 ⑥各类边界值测试介绍 ⑦基于边界值分析方法选择测试用例的原则 ⑧边界值分析法的实例分析 1、边界值分析法的介绍和概念 …

Apipost forEach循环控制器如何使用

最近&#xff0c;Apipost对自动化测试进行了优化&#xff0c;新增foreach控制器。这个新功能的引入为自动化测试带来了更高的效率和灵活性。本文将介绍Apipost的foreach控制器&#xff0c;解释其用途和优势&#xff0c;帮助您更好地利用这一功能提升自己的测试工作。 什么是fo…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(8)模型训练

好吧&#xff0c;搞了半天&#xff0c;都是围绕数据在干活&#xff0c;这也就验证了&#xff0c;我们说的&#xff0c;数据准备等工作&#xff0c;要占到机器学习项目一半以上的工作量和时间。而且数据决定了模型的天花板&#xff0c;算法只是去达到上限。 我们今天来学习模型…

3.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-游戏启动流程的分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;项目搭建 首先下图红框里是游戏启动的程序 游戏启动之后的名字&#xff08;fxgame.exe&#xff09; 一般游戏启动的架构&#xff1a; 第一种&#xff1a;登录器程序启动游戏主程序&#xff0c;然后游…

企业级 文件传输加密应用,干货分享

企业级 文件传输加密应用 简历一直在投&#xff0c;一直无音讯&#xff0c;今天我又从硬盘里翻出一个 好玩的加密软件&#xff0c;这个是 2017年的时候和荷兰某世界500强公司合作的小项目。 今天分享给大家 。 文章目录 企业级 文件传输加密应用1.目的2.软件介绍3.下载好 安装…

多进程(1)

1> 使用多个进程实现文件拷贝 #include<myhead.h> int main(int argc, const char *argv[]) {pid_t pid;pidfork();int fdr;char buf;if((fdropen(argv[1],O_RDONLY))-1){perror("open error");return -1;}int lenlseek(fdr,0,SEEK_END)-lseek(fdr,0,SEEK_…

基于springboot实现的音乐网站

一、系统架构 前端&#xff1a;html | js | css | bootstrap 后端&#xff1a;springboot | mybatis 环境&#xff1a;jdk1.8 | mysql | maven 二、 代码及数据库 三、功能介绍 01. 登录页 02. 用户注册 03. 首页 04. 喜欢 05. 查询

银河麒麟操作系统自动同步时间更新

1、银河麒麟操作系统基于Centos8的&#xff0c;因centos8取消了ntp服务器&#xff0c;所以导致之前使用ntpdate命令无法同步时间 2、centos默认使用chrony模块来进行同步时间 3、修改chrony配置同步时间服务器 vim /etc/chrony.conf 4、目前使用的是阿里云的时间服务器&…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(9)模型优化

模型训练后&#xff0c;就要进行模型优化了。 一般来讲&#xff0c;很简单&#xff0c;优化就是不换模型换参数&#xff0c;或者直接换模型。 换了之后来对比&#xff0c;最后选个最好的。 比如在本案例中&#xff0c;选择LinearRegression后&#xff0c;MSE从22下降到12&am…

Caddy 自动HTTPS 反向代理、重定向、静态页面 - docker版

简介 Caddy 是一个通用的、易于使用的 Web 服务器&#xff0c;具有以下特点&#xff1a; 快速: Caddy 使用 Go 语言编写&#xff0c;以高性能著称。 安全: Caddy 支持 HTTPS、自动证书生成、HTTP/2 等安全功能。 易用: Caddy 的配置文件简单易懂&#xff0c;易于配置。 功能丰…