【Linux】驱动程序同步和异步通知方式

一、应用程序APP,访问驱动程序/dev/input/enent1流程:

在这里插入图片描述

假设用户程序直接访问 /dev/input/event0 设备节点,或者使用 tslib 访问设备节点,数据的流程如下:

  1. APP 发起读操作,若无数据则休眠;
  2. 用户操作设备,硬件上产生中断。如用户点击触摸屏,产生SIGIO信号;
  3. 输入系统驱动层对应的驱动程序处理中断: 读取到数据,转换为标准的输入事件,向核心层汇报。 所谓输入事件就是一个“struct input_event”结构体
  4. 核心层可以决定把输入事件转发给上面哪个 handler 来处理。最常用的是 evdev_handler:它只是把 input_event 结构体保存在内核 buffer 等。
  5. 当 APP正在等待数据时,evdev_handler 会把它唤醒,这样 APP 就可以读取数据。 APP 对输入事件的处理: APP 获 得 数据 的 方 法 有 2 种 : 直 接 访 问 设 备 节 点 ( 比 如 /dev/input/event0,1,2,…),或者通过 tslib、libinput 这类库来间接访问设备节点。这些库简化了对数据的处理。



二、标准输入事件–struct input_event

/* The event structure itself */
struct input_event {struct timeval time;__u16 type;__u16 code;__s32 value;
};

在这里插入图片描述



三、驱动程序同步通知方式

所谓同步,就是“你慢我等你”。

fd = open("/dev/input/event1", O_RDWR | O_NONBLOCK);

设置驱动程序为“O_NONBLOCK”表示“非阻塞”。APP 调用 read 函数读取数据时,如果驱动程序中有数据,那么 APP 的 read函数会返回数据。如果驱动程序中没有数据,APP会阻塞。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>int main()
{const char *inputDevicePath = "/dev/input/event0";int inputDeviceFd = open(inputDevicePath, O_RDONLY);if (inputDeviceFd == -1){perror("Failed to open input device");return 1;}struct input_event event;while (1){ssize_t bytesRead = read(inputDeviceFd, &event, sizeof(event));if (bytesRead == -1){perror("Failed to read input event");break;}if (bytesRead == sizeof(event)){// 处理输入设备事件printf("Event type: %d, code: %d, value: %d\n", event.type, event.code, event.value);}}close(inputDeviceFd);return 0;
}



四、驱动程序异步通知方式

所谓异步通知,就是 APP 可以忙自己的事,当驱动程序用数据时它会主动给APP 发信号,这会导致 APP 执行信号处理函数。

驱动程序发信号流程:

  1. 用户点击触摸屏,触摸屏上的驱动从硬件上获得数据,转化为标准输入事件–struct input_event event;
  2. 驱动程序发信号(SIGIO,驱动程序常用信号,表示有IO事件)给应用程序(APP)。怎么发?内核里提供有函数,内核自动处理。

应用程序要做的事情有这几件:

  1. 编写信号处理函数:
void my_sig_handler(int sig)
{struct input_event event;while (read(fd, &event, sizeof(event)) == sizeof(event)){printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);		}
}
  1. 注册信号处理函数:
signal(SIGIO, my_sig_handler);
  1. 打开驱动程序:
fd = open("/dev/input/event0", O_RDWR);
  1. 把APP的进程 ID 告诉驱动,getpid()可以获得应用程序的进程id。这一步是核心,告诉驱动程序应该把信号发给哪个APP
fcntl(fd, F_SETOWN, getpid());
  1. 使能驱动的 FASYNC 功能:
flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | FASYNC);

驱动程序的信号发给APP的关键是:APP 要把自己的pid告诉驱动。 APP 收到后,执行信号处理函数。




参考链接:
Linux中如何获取输入设备(如触摸屏、按键等)的事件信息

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS 数据持久化 Preferences 如何在页面中对数据进行读写

背景介绍 最近在了解并跟着官方文档尝试做一个鸿蒙app 小demo的过程中对在app中保存数据遇到些问题 特此记录下来 这里的数据持久化以 Preferences为例子展开 废话不多说 这里直接上节目(官方提供的文档示例:) 以Stage模型为例 1.明确preferences的类型 import data_prefer…

【TinyALSA全解析(二)】wav和pcm音频文件格式详解

wav和pcm音频文件格式详解 一、本文的目的二、wav和pcm格式文件介绍三、pcm格式文件解析四、wav文件内容解析4.1 文件内容描述4.2 实战分析 五、如何在各种音频格式之间进行转换 /******************************************************************************************…

jetson nano 串口通信

目录 1.UART通信介绍 2.电脑端准备工作 2.1 安装串口调试助手 2.2 硬件接线 3.Jetson Nano端准备工作 3.1安装库文件 3.2修改主板上电启动串口权限 4.示例程序-发送及接收 4.1 开启串口调试助手 4.2 导入示例程序 4.3 执行程序 4.4 查看效果 4.4.1 串口调试端 4.4…

【Java Spring】SpringBoot 日志系统

文章目录 一、Spring Boot 日志系统1.1 Spring Boot 日志框架1.2 自定义日志打印1.3 日志级别设置1.4 日志持久化1.5 lombok 简化日志输出 一、Spring Boot 日志系统 1.1 Spring Boot 日志框架 SLF4J 和 logback都是spring boot内置的日志框架&#xff0c;开发者只负责调用对…

蓝桥杯第100 题 九宫幻方 DFS 全排列 C++ 解题思维

题目 九宫幻方https://www.lanqiao.cn/problems/100/learning/?page1&first_category_id1&name%E4%B9%9D 思路和解题方法 一 &#xff08;DFS) 首先&#xff0c;定义了一些全局变量和数组。vis数组用于标记已经出现过的数字&#xff0c;a数组用于存储数独的初始状态…

ensp 启动设备时报40错误,然后一直没有去管,再次进去就好了,我知道是配置虚拟机的时候修改了一些设置:

第一个阶段&#xff1a; 那时我是重置电脑之后就安装了ensp所以没有出现什么问题&#xff0c;&#xff08;那时没有导入ce6800和12800还有防火墙6000&#xff09; 第二个阶段&#xff1a; 因为有华为相关的实验要做&#xff0c;所以心血来潮打开了ensp&#xff08;路由器之前…

多类场景、遍布各地,融云 IM 支撑多款应用全球增长

&#xff08;全网都在找的《社交泛娱乐出海作战地图》&#xff0c;点击获取&#x1f446;&#xff09; 无论是面向企业场景的工作流协同还是消费场景的网络效应形成&#xff0c;商务社交还是陌生人社交&#xff0c;IM 都是必备组件。IM 遍布互联网各角落&#xff0c;出现在所有…

算法通关村第十二关-黄金挑战字符串冲刺题

最长公共前缀 描述 : 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 题目 : LeetCode 14.最长公共前缀 : 分析 : 第一种方式&#xff0c;我们可以竖着比较&#xff0c;如图所示&#xff0c;每前进一个位置就…

unity学习笔记06

一、预制体 1.定义&#xff1a; 预制体是一种存储了一个或多个游戏对象及其组件的资产。可以将预制体视为游戏对象的模板&#xff0c;它包含了对象的所有属性、组件和初始状态。 2.创建预制体&#xff1a; 在Unity中&#xff0c;可以通过将一个或多个游戏对象拖动到项目窗口…

量子计算软件平台

目录 1.量子语言 2.量子软件开发工具 3.量子云计算平台 1.量子语言 量子语言是一种基于量子计算机的语言&#xff0c;用于描述和实现量子算法。与经典计算机语言不同&#xff0c;量子语言需要考虑量子力学的特殊规则和算法的量子化。其中&#xff0c;最常用的量子语言是量子程…

xxljob学习笔记01(小滴课堂)

分布式调度xxl-job源码部署和数据库建立&#xff1a; 在idea中打开安装包&#xff1a; 创建数据库&#xff1a; 建表&#xff1a; 在项目里&#xff1a; 在navicat里运行语句即可&#xff1a; 修改数据库地址和用户名&#xff0c;密码&#xff1a; 配置令牌&#xff0c;不然谁…

ESP32-Web-Server编程- JS 基础5

ESP32-Web-Server编程- JS 基础5 概述 JS 编程内容颇多&#xff0c;我们提供一些简单的示例&#xff0c;先玩再学&#xff0c;边玩边学。 示例1-演示通过 JS 进行温度转换 资源链接 对应示例的 code 链接 &#xff08;点击直达代码仓库&#xff09; 示例2-增加网页弹窗 演…