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

linux驱动之input子系统简述

文章目录

  • 一、什么是input子系统
  • 二、内核代码
  • 三、代码分析

一、什么是input子系统

Input驱动程序是linux输入设备的驱动程序,我们最常见的就按键,触摸,插拔耳机这些。其中事件设备驱动程序是目前通用的驱动程序,可支持键盘、鼠标、触摸屏等多种输入设备。
Linux input 子系统将一个输入设备的输入过程分成了设备驱动(input device driver)和事件驱动(input event driver)两个层。前者负责从底层硬件采集数据;后者负责与用户程序接口,将采集到的数据分发给不同的用户接口。
通过这样的设计,将千差万别的设备统一到了为数不多的几种驱动接口上。同一种事件驱动可以用来处理多个同类设备;同一个设备也可以和多种事件驱动相衔接。而事件驱动和设备驱动则由输入核心层进行连接,匹配。

在这里插入图片描述这个是网上赵的一张图,写的还是很详细的。

二、内核代码

位置:

相关代码位置在: Linuxdrivers/input这个目录 

常见的驱动有这些

tony@lc:~/sdcard/imx6ull-pro/Linux-4.9.88/drivers/input$ ls
apm-power.c  ff-memless.c    input-leds.c     joydev.c         misc             tablet
built-in.o   gameport        input-leds.o     joystick         mouse            touchscreen
evbug.c      input.c         input-mt.c       Kconfig          mousedev.c
evdev.c      input-compat.c  input-mt.o       keyboard         mousedev.o
evdev.o      input-compat.h  input.o          Makefile         rmi4
ff-core.c    input-compat.o  input-polldev.c  matrix-keymap.c  serio
ff-core.o    input-core.o    input-polldev.o  matrix-keymap.o  sparse-keymap.c

三、代码分析

我们主要关注三个函数:
input_dev 表示一个输入设备,包含输入设备的一些相关信息;
内核中通过这个结构体来填充输入设备,填充后通过input_register_device来注册就好了
一旦我们注册成功,我们就可以在对应的目录下看到
所有的输入设备都存在这个input_dev中。

struct input_dev {const char *name;const char *phys;const char *uniq;struct input_id id;unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];unsigned long evbit[BITS_TO_LONGS(EV_CNT)];unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];unsigned long relbit[BITS_TO_LONGS(REL_CNT)];unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];unsigned long swbit[BITS_TO_LONGS(SW_CNT)];unsigned int hint_events_per_packet;unsigned int keycodemax;unsigned int keycodesize;void *keycode;int (*setkeycode)(struct input_dev *dev,const struct input_keymap_entry *ke,unsigned int *old_keycode);int (*getkeycode)(struct input_dev *dev,struct input_keymap_entry *ke);struct ff_device *ff;unsigned int repeat_key;struct timer_list timer;int rep[REP_CNT];struct input_mt *mt;struct input_absinfo *absinfo;unsigned long key[BITS_TO_LONGS(KEY_CNT)];unsigned long led[BITS_TO_LONGS(LED_CNT)];unsigned long snd[BITS_TO_LONGS(SND_CNT)];unsigned long sw[BITS_TO_LONGS(SW_CNT)];int (*open)(struct input_dev *dev);void (*close)(struct input_dev *dev);int (*flush)(struct input_dev *dev, struct file *file);int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);struct input_handle __rcu *grab;spinlock_t event_lock;struct mutex mutex;unsigned int users;bool going_away;struct device dev;struct list_head	h_list;struct list_head	node;unsigned int num_vals;unsigned int max_vals;struct input_value *vals;bool devres_managed;
};

可以通过下面的命令进行查看现在有哪些事件

# ls sys/class/input/
event0  event1  event2  input0  input1  input2  mice

input_handler 这个是代表的处理类型 比如我们的耳机插入和我们触摸屏幕就是不同的类型
一个input_handler 可以处理多个input_dev 比我们的音量加减,屏幕亮灭的事件处理都是可以通过同一个handler来处理
struct input_handler {

	void *private;void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);void (*events)(struct input_handle *handle,const struct input_value *vals, unsigned int count);bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);bool (*match)(struct input_handler *handler, struct input_dev *dev);int (*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);bool legacy_minors;int minor;const char *name;const struct input_device_id *id_table;struct list_head	h_list;struct list_head	node;
};

input_handle 因为一个 input_handler 可以处理多个event ,如果不进行管理的话,就会很乱,所以我们需要一个管理者来管理,所以抽象一个input_handle 来把 input_handler和input_dev联系起来,就好像input_dev是横坐标 input_handler 是纵坐标, input_handle就是交点,每一个交点都是一个input节点。

struct input_handle {void *private;int open;const char *name;struct input_dev *dev;struct input_handler *handler;struct list_head	d_node;struct list_head	h_node;
};

一个按键驱动的大概步骤是这样的 :

 
struct input_dev *inputdev; /* input 结构体变量 *//* 驱动入口函数 */static int __init xxx_init(void)
{......inputdev = input_allocate_device(); /* 申请 input_dev */inputdev->name = "test_inputdev"; /* 设置 input_dev 名字 *//*********第一种设置事件和事件值的方法***********/__set_bit(EV_KEY, inputdev->evbit); /* 设置产生按键事件 */__set_bit(EV_REP, inputdev->evbit); /* 重复事件 */__set_bit(KEY_0, inputdev->keybit); /*设置产生哪些按键值 *//************************************************//*********第二种设置事件和事件值的方法***********/keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) |BIT_MASK(EV_REP);keyinputdev.inputdev->keybit[BIT_WORD(KEY_0)] |=BIT_MASK(KEY_0);/************************************************//*********第三种设置事件和事件值的方法***********/keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) |BIT_MASK(EV_REP);input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0);/************************************************//* 注册 input_dev */input_register_device(inputdev);......return 0;
}/* 驱动出口函数 */
static void __exit xxx_exit(void)
{input_unregister_device(inputdev); /* 注销 input_dev */input_free_device(inputdev); /* 删除 input_dev */
}

我们在ui界面上为了可以更加快速的反馈时间,就需要在内核中将事件上报上去,这样我们UI就可以及时的进行处理。
上报事件就是通过 input_event 上报event 事件。

我们获取健值这些,其实也是通过open wirte函数这些去获取的。

参考博客:input子系统

相关文章:

linux驱动之input子系统简述

文章目录 一、什么是input子系统二、内核代码三、代码分析 一、什么是input子系统 Input驱动程序是linux输入设备的驱动程序,我们最常见的就按键,触摸,插拔耳机这些。其中事件设备驱动程序是目前通用的驱动程序,可支持键盘、鼠标…...

嵌入式裸机架构的探索与崩塌

为什么会想着探索下嵌入式裸机的架构呢?是因为最近写了一个项目,项目开发接近尾声时,发现了一些问题: 1、项目中,驱动层和应用层掺杂在一起,虽然大部分是应用层调用驱动层,但是也存在驱动层调用…...

MySQL高级语句(第二部分)

MySQL高级语句(第二部分)一、视图表 create view1、视图表概述2、视图表能否修改?(面试题)3、基本语法3.1 创建3.2 查看3.3 删除 4、通过视图表求无交集值 二、case语句三、空值(null) 和 无值(’ ) 的区别四、正则表达式五、存储过程1、简介…...

HTML计时事件(JavaScript)网页电子钟+网页计时器

setTimeout("函数","未来指定毫秒后调用函数"); clearTimeout(setTimeout("函数","未来指定毫秒后调用函数")); <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title>…...

使用群晖实现Videostation电影的大容量存储及分享教程

文章目录 1.使用环境要求2.制作视频分享链接3.制作永久固定视频分享链接 李哥和他的女朋友是一对甜蜜的情侣&#xff0c;但不幸的是&#xff0c;由于工作原因&#xff0c;他们目前分隔两地&#xff0c;无法常常亲密相伴。 这个距离让李哥特别怀念和女朋友一起在电影院观看电影的…...

后端大厂面试-15道题

1. 说说计算机存储结构 计算机存储结构通常包括这几个层次&#xff1a; 主存储器&#xff08;Main Memory&#xff09;&#xff1a;也称为内存&#xff08;RAM&#xff0c;Random Access Memory&#xff09;&#xff0c;主要用于存储当前正在执行的程序和数据。它是计算机中最…...

C++: 冒泡排序(Bubble Sort)

假设你有一列由数字组成的玻璃珠&#xff0c;这些珠子的重量不同&#xff0c;你希望将它们按照重量从轻到重排列。你会这样做&#xff1a; 从左到右&#xff0c;比较相邻的两颗珠子的重量。如果左边的珠子比右边的珠子重&#xff0c;就交换它们的位置。然后&#xff0c;继续向…...

跨域的解决方案

文章目录 概念一、什么是跨域问题二、为什么会发生跨域问题三、跨域解决方案1、JSONP2、添加响应头3、Spring注解CrossOrigin4、配置文件&#xff08;常用&#xff09;5、nginx跨域 概念 一、什么是跨域问题 前端调用的后端接口不属于同一个域&#xff08;域名或端口不同&…...

如何使用Java语言判断出geek是字符串参数类型,888是整数参数类型,[hello,world]是数组参数类型,2.5是双精度浮点数类型?

如何使用Java语言判断出geek是字符串参数类型&#xff0c;888是整数参数类型&#xff0c;[hello,world]是数组参数类型&#xff0c;2.5是双精度浮点数类型&#xff1f; Java是一种静态类型的编程语言&#xff0c;这意味着我们需要在编译时为变量指定具体的类型。但是&#xff…...

9.20华为机试-后端

1、丢失报文的位置 某通信系统持续向外发送报文&#xff0c;使用数组 nums 保存 n个最近发送的报文&#xff0c;用于在报文未达到对端的情况下重发。报文使用序号 sn 表示&#xff0c;序号 sn 按照报文发送顺序从小到大排序&#xff0c;相邻报文 sn 不完全连续且有可能相同。报…...

LC926. 将字符串翻转到单调递增(JAVA - 动态规划)

将字符串翻转到单调递增 题目描述动态规划 题目描述 难度 - 中等 LC926. 将字符串翻转到单调递增(JAVA - 动态规划) 如果一个二进制字符串&#xff0c;是以一些 0&#xff08;可能没有 0&#xff09;后面跟着一些 1&#xff08;也可能没有 1&#xff09;的形式组成的&#xff0…...

【高阶数据结构】哈希的应用 {位图;std::bitset;位图的应用;布隆过滤器;布隆过滤器的应用}

一、位图 1.1 位图概念 面试题 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。【腾讯】 遍历查找&#xff1a;内存中无法存放40亿个整数&#xff08;约占内存15-16G&#xff09;&#xff1b;时间复杂…...

金融生产存储亚健康治理:升级亚健康 3.0 ,应对万盘规模的挑战

随着集群规模的不断扩大&#xff0c;硬盘数量指数级上升&#xff0c;信创 CPU 和操作系统、硬盘多年老化、物理搬迁等多种复杂因素叠加&#xff0c;为企业的存储亚健康管理增加了新的挑战。 在亚健康 2.0 的基础上&#xff0c;星辰天合在 XSKY SDS V6.2 实现了亚健康 3.0&#…...

C语言自定义类型讲解:结构体,枚举,联合(2)

&#x1f435;本篇文章将会对位段、枚举和联合的相关知识进行讲解 1. 位段&#x1f4da; 1.1 什么是位段 位段的声明和结构体类似&#xff0c;但是有两点不同&#xff1a; 1.位段的成员必须是int&#xff0c;unsigned int&#xff0c;signed int (C99之后也可以是其他成员&am…...

AI编程助手 Amazon CodeWhisperer 全面解析与实践

目录 引言Amazon CodeWhisperer简介智能编程助手智能代码建议代码自动补全 提升代码质量代码质量提升安全性检测 支持多平台多语言 用户体验和系统兼容性用户体验文档和学习资源个性化体验系统兼容性 功能全面性和代码质量功能全面性代码生成质量和代码安全性 CodeWhisperer的代…...

利用EXCEL进行XXE攻击

利用EXCEL进行XXE攻击 原因 原因 Microsoft Office从2007版本引入了新的开放的XML文件格式&#xff0c;新的XML文件格式基于压缩的ZIP文件格式规范&#xff0c;由许多部分组成。 我们可以将其解压缩到特定的文件夹中来查看其包含的文件夹和文件&#xff0c;可以发现其中多数是…...

芯片验证就是一次旅行

如果你国庆希望去一个你不曾去过的城市旅行&#xff0c;比如“中国苏州”。对游客来说&#xff0c;它是个蛮大的城市&#xff0c;有许多景点可以游玩&#xff0c;还有许多事情可以做。但实际上&#xff0c;即使最豪也最清闲的游客也很难看苏州的所有方方面面。同样的道理也适用…...

Java深入理解线程的三大特性

目录 1 CPU缓存导致可见性问题2 线程切换导致原子性问题3 性能优化导致有序性问题4 JMM(Java Memory Model)5 volatile6 synchronized 1 CPU缓存导致可见性问题 线程的三大特性&#xff1a; 可见性&#xff1a;Visibility有序性&#xff1a;Ordering原子性&#xff1a;Atomic…...

2025快手校招面试真题汇总及其解答(二)

6. hashmap数据结构 HashMap 是一种散列表,它是一种根据键值对来存储数据的数据结构。HashMap 的特点是插入、查找和删除操作的时间复杂度都是 O(1),因此它是一种非常高效的数据结构。 HashMap 的工作原理是将键值对存储在一个数组中,每个键值对都由一个哈希函数来映射到数…...

PHP生成带中文的图片

imagettftext() 函数是 PHP 中的一个内置函数&#xff0c;用于使用 TrueType 字体将文本写入图像。 句法&#xff1a; 数组imagettftext&#xff08;资源$image&#xff0c;float $size&#xff0c;float $angle&#xff0c; int $x&#xff0c;int $y&#xff0c;…...

利用Taotoken用量看板精细化管理团队大模型API消费

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 利用Taotoken用量看板精细化管理团队大模型API消费 对于团队管理者而言&#xff0c;在引入大模型能力后&#xff0c;一个普遍存在的…...

3步实现微信聊天记录永久备份:WeChatExporter完整解决方案

3步实现微信聊天记录永久备份&#xff1a;WeChatExporter完整解决方案 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因手机丢失或系统更新而永远丢失珍贵的微信…...

Shermie-proxy:基于Node.js的脚本化HTTP/HTTPS代理调试工具实战指南

1. 项目概述与核心价值最近在折腾一些本地开发环境下的网络请求调试和抓包&#xff0c;发现一个挺有意思的开源项目kxg3030/shermie-proxy。这本质上是一个基于 Node.js 实现的 HTTP/HTTPS 代理服务器&#xff0c;但它的定位非常清晰&#xff1a;专为开发者本地调试和网络请求分…...

DETR模型ONNX推理实战:从输出张量到可视化检测框的完整解析

DETR模型ONNX推理实战&#xff1a;从输出张量到可视化检测框的完整解析 在目标检测领域&#xff0c;DETR&#xff08;Detection Transformer&#xff09;以其独特的端到端架构和简洁的流程设计&#xff0c;正在改变传统基于锚框&#xff08;anchor-based&#xff09;方法的格局…...

ENVI 5.6 + COSI-Corr插件整合指南:搞定地表形变分析的第一步

ENVI 5.6 COSI-Corr插件整合指南&#xff1a;搞定地表形变分析的第一步 对于地质测绘领域的研究人员和工程师来说&#xff0c;地表形变监测是理解地质灾害、评估基础设施安全的重要技术手段。在众多遥感分析方法中&#xff0c;COSI-Corr&#xff08;Co-registration of Optic…...

3分钟掌握Joy-Con Toolkit:让你的Switch手柄焕然一新的终极指南

3分钟掌握Joy-Con Toolkit&#xff1a;让你的Switch手柄焕然一新的终极指南 【免费下载链接】jc_toolkit Joy-Con Toolkit 项目地址: https://gitcode.com/gh_mirrors/jc/jc_toolkit 还在为单调的Joy-Con手柄配色而烦恼吗&#xff1f;Joy-Con Toolkit为你带来了一键改变…...

Hyper-V DDA图形工具:告别PowerShell命令行的设备直通新时代

Hyper-V DDA图形工具&#xff1a;告别PowerShell命令行的设备直通新时代 【免费下载链接】DDA 实现Hyper-V离散设备分配功能的图形界面工具。A GUI Tool For Hyper-Vs Discrete Device Assignment(DDA). 项目地址: https://gitcode.com/gh_mirrors/dd/DDA 还在为Hyper-…...

告别Spoon客户端!手把手教你用这个Vue+SpringCloud的Kettle Web版开源工具

从桌面到云端&#xff1a;基于VueSpringCloud的Kettle Web化实践指南 对于长期使用Kettle Spoon客户端的ETL工程师而言&#xff0c;反复安装Java环境、处理客户端兼容性问题、在多台机器间同步配置已成为日常痛点。当团队需要协作开发或管理远程服务器上的数据集成任务时&…...

从原理到批量利用:深入剖析Apache Superset默认密钥漏洞(CVE-2023-27524)

1. Apache Superset安全漏洞背景 Apache Superset作为一款流行的开源数据可视化工具&#xff0c;在企业数据分析领域有着广泛应用。但正是这样一个看似无害的工具&#xff0c;却因为开发者的一个常见疏忽——使用默认密钥&#xff0c;导致了严重的身份验证绕过漏洞。这个编号为…...

Cursor IDE事件日志分析工具:Python实现开发者行为可视化与效率洞察

1. 项目概述&#xff1a;一个为开发者“把脉”的智能分析工具如果你是一名开发者&#xff0c;尤其是深度使用Cursor这类AI编程助手的开发者&#xff0c;你肯定有过这样的体验&#xff1a;面对一个复杂的项目&#xff0c;你向AI助手提了无数个问题&#xff0c;生成了大量代码片段…...