笔记整理—linux驱动开发部分(10)input子系统与相关框架
关于输入类设备的系统有touch、按键、鼠标等,在系统中,命令行也是输入类系统。但是GUI的引入,不同输入类设备数量不断提升,带来麻烦,所以出现了struct input_event。
struct input_event {struct timeval time;//内核用于描述时间点的时间结构体__u16 type;//什么类型的事件(如案件类)__u16 code;//什么按键(如按键1)__s32 value;//值(按下)
};//去描述一次输入类事件
input子系统分为四个部分:应用层、input_event(事件,是驱动层到应用层)+input_core(核心,就是框架)+硬件驱动。
中断事件去唤醒input子系统,从驱动->input_core->input_event->应用层,向应用层返回一个input_event。
事件驱动里的GUI框架:QT(信号与槽),VC等。等待事件发生,执行下一步过程,等待过程中,处于平衡状态。应用层的信号与槽可以理解为嵌入式系统中的中断与中断处理程序。
应用层的使用方法:/device设备文件;/sys属性文件。
但是input子系统等的为/dev/input/xxx(event n n=0、1、2......)。使用cat去确认event对应的设备,但是cat去read一个input设备时,若无输入则会阻塞,直到有输入信息出现。
int fd = -1, ret = -1;
struct input_event ev;fd = open(DEVICE_KEY, O_RDONLY);
if (fd < 0)
{perror("open");return -1;
}while (1){//读取一个event事件包memset(&ev, 0, sizeof(struct input_event));ret = read(fd, &ev, sizeof(struct input_event));if (ret != sizeof(struct input_event)){perror("read");close(fd);return -1;}// 解析event包,才知道发生了什么样的输入事件printf("%s.\n", (unsigned char *)&ev); }//关闭设备
close(fd);
input子系统框架:
首先,确认一个三层思想:最上层的输入事件驱动层;中间的输入核心层;最下层的输入设备驱动层。输入事件驱动层evdev.c mousedev.c 其被剥离与下面两层。输入核心层是input.c输入核心层解析,而这两层是内核相关层,维护归属于内核开发者,。最下层是输入设备驱动类,有各种文件夹,里面有各种设备驱动,归属于驱动开发者进行维护。
因为输入事件驱动层存在四种平行层,所以应剥离于输入核心层,不同设备以适应不同的特性(Keyboard Hander、Mouse Hander;Joystick Hander;Event Hander)。最后的Event Hande模型达到了最大的兼容,可以兼容上面3个模型。
一个事件支持一对多模型发送到应用层。
在开发驱动过程中,只需要去写/改最下层,上中两层是内核开发人员进行维护的,中间的一层只是为驱动写了一些接口,模型已经定义完成,开发者核心工作将是在驱动的调优方向。
输入核心层以一个模块编译到内核中input_input();class_register()注册了input类/sys/class/input;input_proc_init()是procfs初始化;register_chrdev()注册字符类设备。
设备驱动层接口函数(在中间层实现)
input_allocate_device();//申请dev,初步初始化input_dev
input_set_capability();//设置输入事件能力(接收上面事件)可多次调用
input_register_device();//注册dev
顺序执行上述代码
一个鼠标最少应调用input_set_capabitity 4次声明能力为BTN_LEFT;BTN_RIGHT;REL_X;REL_Y这四个宏定义。
__set_bit(EV_SYN,dev_evbit)在register_device中调用,使dev有发送同步包的能力。
init_timer();//内核定时器
list_add_tail();//添加链表完成注册
list_for_each_entry();//遍历dev与handler方法匹配
input_attach_handler();//handler->comect();//最终实现device与handler挂接
input_match_device()中进行关于总线、厂商等的对比,最终实现handler匹配,其位置在handler->connect()之前。
事件驱动层接口函数:
int input_register_handler(struct input_handler *handler);
int input_register_handle(struct input_handle *handle);input_register_handler();INIT_LIST_HEAD(&handler->h_list);list_add_tail(&handler->node, &input_handler_list);input_table[8];//指针数组,指向input_handler(表示最多允许注册8种handler)大多数用event_handler
一个硬件匹配两个handler会匹配2个设备号(次)与各自设备文件相绑定:
handler->minor>>5 =>minor/32=input_table[下标]。
注册handler时去dev_list()在找匹配对象。注册dev时去handler_list()中找匹配对象。
input_register_handle用于处理dev与handler关系。
事件驱动层框架 evdev.c/mouse.c是一种handler。
evdev_init()input_register_handler()核心层已经实现,handler去调用
input_handler结构体:
struct input_handler {void *private;//指向一个结构体void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);//硬件信息加工bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);bool (*match)(struct input_handler *handler, struct input_dev *dev);//支持自有matchint (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);//匹配上连接void (*disconnect)(struct input_handle *handle);//断开连接void (*start)(struct input_handle *handle);const struct file_operations *fops;//对应应用层使用方法//一些设备信息int minor;const char *name;const struct input_device_id *id_table;//handler支持设备特征,用于match匹配//handler与dev链表struct list_head h_list;struct list_head node;
};
.read方法:①获取信息;②信息校验(结构体大小、client等);③input_event_to_user将event发送到用户层,wait_evebt_interruptible等待event信息(应用层等待事件实现)在.event中唤醒。
.connect方法,在匹配上后调用(match):①minor校验;②内存开辟;③数据填充;④MKDEV填充次设备号;⑤device_initialize()+⑦device_add完成device_register;⑥input_register_handle注册handle放链表中。
.event方法,封装硬件层信息为struct发送到user:①获取驱动信息(时间部分-内核时间);②evdev_pass_event()发送到那个handler(支持多个handler发送)是一种通知方式(放buffer)用wake_lock_timeout设置唤醒时钟,kill_fasync()发异步通知(谁关注发谁)异步通知+多路IO复用。
在X210中,官方实现的按键发送值与规范方法不同,不是很规范。
.probe=s3c_button_probe
platform+input总线实现。driver+dev=>probe=驱动;input+驱动=>发包应用层。在x210按键消息可见Button_x210.c。
GPIO_SFN(n)//模式
BITS_TO_LONGS(X)//几个32为的long能放下x个bit数据,有余数就向上兼容
set_bit();//向位图设置相应位
handler与dev匹配通过input->id.bustype ;input->id.vendor;input->id.product;input->id.version,进行匹配。
.probe①申请GPIO;②设置GPIO;③申请input空间;④填空input;⑤注册input;⑥启动定时器(等待一定时间完成消抖或轮询)。
/proc/interrupts记录了内核注册的中断。
相关文章:
笔记整理—linux驱动开发部分(10)input子系统与相关框架
关于输入类设备的系统有touch、按键、鼠标等,在系统中,命令行也是输入类系统。但是GUI的引入,不同输入类设备数量不断提升,带来麻烦,所以出现了struct input_event。 struct input_event {struct timeval time;//内核…...
[算法初阶]埃氏筛法与欧拉筛
素数的定义: 首先我们明白:素数的定义是只能整除1和本身(1不是素数)。 我们判断一个数n是不是素数时,可以采用试除法,即从i2开始,一直让n去%i,直到i*i<n c语言: #include<…...
【THM】linux取证 DisGruntled
目录 0x00 房间介绍 0x01 连接并简单排查 0x02 让我们看看做没做坏事 0x03 炸弹已埋下。但何时何地? 0x04 收尾 0x05 结论 0x00 房间介绍 嘿,孩子!太好了,你来了! 不知道您是否看过这则新闻,我…...
SpringBoot整合Freemarker(四)
escape, noescape 语法 <#escape identifier as expression>...<#noescape>...</#noescape>... </#escape> 用例 主要使用在相似的字符串变量输出,比如某一个模块的所有字符串输出都必须是html安全的,这个时候就可以使用&am…...
centos docker 安装 rabbitmq
安装docker 1.更新现有的软件包 首先,确保您的系统是最新的,可以通过运行以下命令来实现: sudo yum update -y 2.移除旧版本的Docker 如果您之前安装过Docker,可能需要先卸载旧版本。使用以下命令来卸载旧版本的Docker&#…...
手动实现promise的all,race,finally方法
Promise.all 是一个非常有用的工具,它接受一个 Promise 对象数组,并返回一个新的 Promise。当所有输入的 Promise 都成功解决时,新的 Promise 会解决为一个包含所有结果的数组;如果任何一个 Promise 被拒绝,新的 Prom…...
H5移动端预览PDF方法
新建页面 新建一个页面以便去预览对应的pdf 新建完后在 pages.json 文件内去新增对应路由 页面内容 <template><view class"page"><view class"pdf"><view id"demo"></view></view><view class"b…...
uniapp—android原生插件开发(1环境准备)
本篇文章从实战角度出发,将UniApp集成新大陆PDA设备RFID的全过程分为四部曲,涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程,轻松应对安卓原生插件开发与打包需求! 项目背景: UniApp集成新大陆P…...
《潜行者2切尔诺贝利之心》游戏引擎介绍
潜行者2切尔诺贝利之心是基于虚幻5引擎,所以画面效果大家不必担心。游戏目前已经跳票了很久,预计发售时间是2024 年 11 月 21 日,这次应该不会再跳票。 潜行者2切尔诺贝利之心是虚幻5吗 答:是虚幻5。 潜行者官方推特之前回复了…...
winform 加载 office excel 插入QRCode图片如何设定位置
需求:winform 加载 office excel 并加载QRCode图片,但是每台PC打印出来QRCode位置都不太一样,怎么办呢? 我的办法: 1、在sheet中插入一个 textbox ,改名 qrcode (这个名字随便设置)…...
简易入手《SOM神经网络》的本质与原理
原创文章,转载请说明来自《老饼讲解神经网络》:www.bbbdata.com 关于《老饼讲解神经网络》: 本网结构化讲解神经网络的知识,原理和代码。 重现matlab神经网络工具箱的算法,是学习神经网络的好助手。 目录 一、入门原理解说 01.…...
21.assert断言
assert(断言)主要用于在程序运行过程中检查某个条件是否满足,如果不满足则会触发错误并终止程序执行,可以帮助程序员在开发阶段及时发现可能存在的逻辑错误等问题。 通过断言调试程序,abotr() has been called 就是断言…...
15分钟学 Go 第 46 天 : 监控与日志
第46天:监控与日志 学习目标 了解如何实现应用监控与日志管理,掌握相关工具和最佳实践。 内容结构 引言监控的概念与工具 监控的定义常见监控工具 日志管理的概念与工具 日志的重要性常见日志管理工具 实现监控与日志的最佳实践 监控指标日志格式 实战…...
BFS 算法专题(四):多源 BFS
目录 1. 01 矩阵 1.1 算法原理 1.2 算法代码 2. 飞地的数量 2.1 算法原理 2.2 算法代码 3. 地图中的最高点 3.1 算法原理 3.2 算法代码 4. 地图分析 4.1 算法原理 4.2 算法代码 1. 01 矩阵 . - 力扣(LeetCode) 1.1 算法原理 采用 BFS 正难…...
基于Spring Boot+Vue的养老院管理系统【原创】
一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构:B/S架构 运行环境:win10/win11、jdk17 前端: 技术:框架Vue.js;UI库:ElementUI; 开发工具&…...
Linux screen和cscope工具使用总结
1 minicom使用 1.1 minicom配置 第一次启动时: 如果输入sudo minicom提示错误,则需: sudo minicom -s 启动 出现配置菜单:选serial port setup 进入串口配置 输入A配置串口驱动为/dev/ttyUSB0 输入E配置速率为115200 8N1 输入F将 …...
深度学习面试八股汇总
按序发布: 深度学习——优化算法、激活函数、归一化、正则化 进入 深度学习——权重初始化、评估指标、梯度消失和梯度爆炸 进入 深度学习——前向传播与反向传播、神经网络(前馈神经网络与反馈神经网络)、常见算法 进入 深度学习——卷积神…...
微服务架构面试内容整理-API 网关-Gateway
Spring Cloud Gateway 是一个用于构建 API 网关的框架,它为微服务架构提供了灵活的路由和过滤功能。作为 Spring Cloud 生态的一部分,Gateway 提供了易于使用的 API 和强大的功能,适合用于现代微服务架构中的请求管理和服务交互。以下是 Spring Cloud Gateway 的主要特点、工…...
22.04Ubuntu---ROS2使用rclcpp编写节点C++
节点需要存在于功能包当中,功能包需要存在于工作空间当中。 所以我们要想创建节点,就要先创建一个工作空间,再创建功能包。 第一步:创建工作空间 mkdir -p chapt2_ws/src/ 第二步:创建example_cpp功能包,…...
XML 现实案例:深入解析与应用
XML 现实案例:深入解析与应用 XML(可扩展标记语言)自1998年成为W3C推荐标准以来,一直是数据交换和存储的重要工具。它是一种用于标记电子文件的结构化语言,使得数据不仅人类可读,而且机器可处理。本文将探讨XML在现实世界中的应用案例,展示其如何在不同领域中发挥作用。…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...
OpenGL-什么是软OpenGL/软渲染/软光栅?
软OpenGL(Software OpenGL)或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式(包括几何处理、光栅化、着色等),不依赖GPU硬件加速。这种模式通常性能较低,但兼容性极强,常用于不支持硬件加速…...
更新 Docker 容器中的某一个文件
🔄 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法,适用于不同场景。 ✅ 方法一:使用 docker cp 拷贝文件到容器中(最简单) 🧰 命令格式: docker cp <…...
代理服务器-LVS的3种模式与调度算法
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器,其中以Nginx为主,本章我们来讲解几个代理软件:…...
STM32 低功耗设计全攻略:PWR 模块原理 + 睡眠 / 停止 / 待机模式实战(串口 + 红外 + RTC 应用全解析)
文章目录 PWRPWR(电源控制模块)核心功能 电源框图上电复位和掉电复位可编程电压监测器低功耗模式模式选择睡眠模式停止模式待机模式 修改主频一、准备工作二、修改主频的核心步骤:宏定义配置三、程序流程:时钟配置函数解析四、注意…...
