笔记整理—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在现实世界中的应用案例,展示其如何在不同领域中发挥作用。…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...