Linux input输入子系统

Linux input

更多内容可以查看我的github

Linux输入子系统框架

请添加图片描述Linux输入子系统由驱动层、核心层、事件处理层三部分组成。

  • 驱动层:输入设备的具体驱动程序,负责与具体的硬件设备进行交互,并将底层的硬件输入转化为统一的事件形式,向核心层发送
  • 核心层:连接驱动层和事件处理层,负责对下层提供驱动层借口,向上层提供事件处理接口
  • 事件处理层:负责对输入事件进行处理,并将处理结果传递给应用程序
  • 层的设备抽象出对应的接口提供给应用层。将底层设备的触发的事件通过这个接口传达给应用层。

核心层的代码在 linux/drivers/input/input.c 中实现

重要结构体

input_dev

这个结构体属于驱动层,描述了一个具体的input设备,记录相关的硬件信息,事件位图等,

struct input_dev {const char *name;       // 设备名称struct input_id id;     // 设备id,存储输入设备的总线、厂商等信息...unsigned long evbit[BITS_TO_LONGS(EV_CNT)];     // 支持事件类型unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];   // 按键位图unsigned long relbit[BITS_TO_LONGS(REL_CNT)];   // 相对位移位图...struct list_head	h_list;     // 内核链表头struct list_head	node;       // 内核链表节点
};

Linux设备支持的事件类型:

事件类型编码事件描述
EV_SYN0x00同步事件
EV_KEY0x01按键事件(鼠标,键盘等)
EV_REL0x02相对坐标(如:鼠标移动,报告相对最后一次位置的偏移)
EV_ABS0x03绝对坐标(如:触摸屏或操作杆,报告绝对的坐标位置)
EV_MSC0x04其它
EV_SWx05开关
EV_LED0x11按键/设备灯
EV_SND0x12声音/警报
EV_REP0x14重复
EV_FFx15力反馈
EV_PWR0x16电源
EV_FF_STATUS0x17力反馈状态
EV_MAX0x1f事件类型最大个数和提供位掩码支持
input_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设备和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;
};
input_handle_list
struct input_handle_list {struct list_head	list;struct input_handle	*first;struct input_handle	*last;
};
两条重要链表

在 input.c 中,全局维护了两条重要的链表,分别是输入设备链表和事件处理器链表

static LIST_HEAD(input_dev_list);
static LIST_HEAD(input_handler_list);
总结

上面结构体的链表的关系如下面两图所示(这个图好难画-.-,就在网上找了一个,原文连接)

请添加图片描述

请添加图片描述

当我们使用input_register_device()注册一个设备的时候,就会将设备添加到input_dev_list链表中,同时便利input_handler_list进行匹配,匹配成功就会调用input_handler->connect()函数进行连接

事件相关结构体

input_event

事件的输入就是以一个input_event为基本单位的

struct input_event {struct timeval time;  /* 事件发生的时间 */__u16 type;           /* 事件总类型 */__u16 code;           /* 事件子类型 */__s32 value;          /* 事件的值 */
};
evdev_client
struct evdev_client {unsigned int head;unsigned int tail;unsigned int packet_head; /* [future] position of the first element of next packet */spinlock_t buffer_lock; /* protects access to buffer, head and tail */struct fasync_struct *fasync;struct evdev *evdev;struct list_head node;int clk_type;bool revoked;unsigned int bufsize;struct input_event buffer[];
};
  • head:表示客户端缓冲区中下一个要读取的事件的索引。当客户端从缓冲区读取事件时,它会从 buffer[head] 开始读取,并递增 head 的值。因此,head 指向的是最老的未读取事件的位置。
  • tail:表示客户端缓冲区中下一个要写入的事件的索引。当输入事件到达并需要被缓冲时,它将被写入到 buffer[tail] 的位置,并递增 tail 的值。因此,tail 指向的是最新的未写入事件的位置。

实际上,evdev_client 实现了一个环形队列,head是头指针,tail是尾指针,这两个指针都是以 input_event 为单位移动的。

packet_head 与 head 和 tail 不同, 它以数据包(多个input_event)为单位,主要负责记录缓冲区的入口偏移量。

buffer 就是循环队列数组,即缓冲区

所以,根据这些变量我们可以知道,当循环队列满的时候,head = tail;当循环队列空的时候,packet_head = tail

evdev
struct evdev {int open;   // 设备打开计数struct input_handle handle; wait_queue_head_t wait;     // 等待队列,没有事件时进程睡眠struct evdev_client __rcu *grab;    // 事件响应// 客户端链表,可以有多个进程访问设备struct list_head client_list;spinlock_t client_lock; /* protects client_list */struct mutex mutex;struct device dev;struct cdev cdev;bool exist;
};
总结
  • input_event: 表示一个输入事件
  • evdev_client: 表示一个用户空间的应用程序或实体设备与输入设备之间的连接
  • evdev: 输入设备驱动程序的接口实现,应用程序可以通过evdev与evdev_client之间的交互,实现输入事件的读取和输入

流程

这部分建议阅读源码

在输入设备驱动(input_dev)中,一般通过轮询或者中断方式获取事件的原始值,经过一些处理后,通过input_event()函数将数据上报给核心层(input_core)。

在核心层中,通过input_handle_event()input_pass_values()对数据进行处理(type、code、value),然后使用input_to_handler()函数将数据上报给事件处理层(input_handler),在input_to_handler()中,使用input_handler结构体中的事件处理函数(event、events、filter)上报,这些函数可以在evdev.c的1235行的evdev_handler中找到。

在事件处理层中,通过evdev_events()evdev_pass_values()为事件加上时间戳,完成了一个完整的input_event,然后使用__pass_event()将事件传递给用户空间(evdev_client的buffer中)

__pass_event()中,事件input_event会被填充到evdev_clientbuffer中。对于用于空间的应用程序,可以通过read()函数调用内核空间的evdev_read()函数,然后调用evdev_fetch_next_event()函数从环形缓冲区中读取input_event事件

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

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

相关文章

laravel项目配置Facades Redis自动补全,方法查看

问题原因: 因为Laravel的Redis连接实例是通过RedisManger的工厂类创建的,返回的是一个mixin的类型,因此在IDE中不能自动补全Redis的方法,缺少这个功能,使用起来有些麻烦,尤其是Redis有数十个方法,每个方法也有不少参数。 相关部分的代码如下: /*** @mixin \Illumina…

mac电脑鼠标键盘共享软件:ShareMouse for Mac 激活版

ShareMouse 是一款跨平台的键盘和鼠标共享软件,它允许用户在多台计算机之间共享同一组键盘和鼠标,实现无缝的操作和控制。该软件适用于 Windows 和 macOS 系统,并且支持多种连接方式,包括局域网连接和无线连接。 使用 ShareMouse&…

【PHP项目实战训练】——laravel框架的实战项目中可以做模板的增删查改功能(2)

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…

安卓Zygote进程详解

目录 一、概述二、Zygote如何被启动的?2.1 init.zygote64_32.rc2.2 Zygote进程在什么时候会被重启2.3 Zygote 启动后做了什么2.4 Zygote启动相关主要函数 三、Zygote进程启动源码分析3.1 Nativate-C世界的Zygote启动要代码调用流程3.1.1 [app_main.cpp] main()3.1.2…

基于神经网络的教学质量评价模型:深入剖析与实践应用

基于神经网络的教学质量评价模型:深入剖析与实践应用 在教育领域,教学质量评价一直是一项至关重要的任务。随着科技的不断进步,越来越多的先进算法和技术被引入到这一领域,以期提高评价的准确性和客观性。其中,基于神…

Qwen 微调脚本分析 Qwen/finetune.py

Qwen 微调脚本分析 Qwen/finetune.py Qwen/finetune.py : # 基于fastchat和tatsu-lab/stanford_alpaca的修订代码,用于训练语言模型 # 提供使用LoRA(低秩适应)和量化(QLoRA)压缩的选项,以及使…

个人关于ChatGPT的用法及建议

概述 这里只是个人常用的几个软件,做一下汇总,希望对各位有用。 如果有更高认知的朋友,请留下你的工具名称,提醒我一下,谢谢~ 常用的chatgpt模型工具: 以下是一些知名的例子: 文…

代码随想录算法训练营Day55 | 647. 回文子串 516.最长回文子序列 动态规划总结篇

代码随想录算法训练营Day55 | 647. 回文子串 516.最长回文子序列 动态规划总结篇 LeetCode 647. 回文子串 题目链接&#xff1a;LeetCode 647. 回文子串 思路&#xff1a; class Solution { public:int countSubstrings(string s) {vector<vector<bool>> dp(s.…

AI学习指南机器学习篇-多元线性回归

AI学习指南机器学习篇-多元线性回归 在机器学习领域&#xff0c;多元线性回归是一种用于建立自变量和因变量之间关系的模型。在这篇博客中&#xff0c;我们将讨论多元线性回归模型的引入以及它对多个自变量对因变量的影响。我们还将讨论多元线性回归与简单线性回归的区别和应用…

江协科技STM32学习-1 购买24Mhz采样逻辑分析仪

前言&#xff1a; 本文是根据哔哩哔哩网站上“江协科技STM32”视频的学习笔记&#xff0c;在这里会记录下江协科技STM32开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技STM32教学视频和链接中的内容。 引用&#xff1a; STM32入门教程-2023版 细致讲…

CVPR2024 合成异常数据 工业异常检测 RealNet

前言 本文分享一个基于扩散模型的异常检测框架&#xff0c;用于检测工业场景的缺陷检测或异常检测。 强度可控扩散异常合成&#xff1a;基于扩散过程的合成策略&#xff0c;能够生成不同强度的异常样本&#xff0c;模仿真实异常样本的分布。异常感知特征选择&#xff1a;选择…

学习Java,stringbuilder用法

有sb.append添加元素&#xff0c;sb.reverse反转内容&#xff0c;sb.tostring转换成字符串&#xff0c;sb.length计算长度。

东莞酷得智能 组装机械狗电子玩具方案

这款机械狗玩具电子方案结合了现代电子技术和人工智能元素&#xff0c;旨在为用户提供一个高科技、互动性强的娱乐体验。通过不断的软件更新和硬件迭代&#xff0c;机械狗的功能将持续扩展。 一、功能特点&#xff1a; 1、自动巡游&#xff1a;机械狗能够自主在房间内巡游&am…

分库分表、读写分离--ShardingJDBC

1. 项目准备 1.1 建立数据库表 建立user_manage数据库&#xff0c;在该库中建立1张表app_user用来做分库前的测试&#xff0c;另外建12张按月份命名的表app_user_2024XX用来做分库。 CREATE DATABASE IF NOT EXISTS user_manage CHARACTER SET utf8 COLLATE utf8_general_ci…

Python中的__str__和__repr__:揭示字符串表示的奥秘

标题&#xff1a;Python中的__str__和__repr__&#xff1a;揭示字符串表示的奥秘 摘要 在Python中&#xff0c;对象的字符串表示对于调试和日志记录至关重要。__str__和__repr__是两个特殊的方法&#xff0c;用于定义对象的字符串表示形式。尽管它们在功能上相似&#xff0c;…

vm-bhyve网卡设定桥接故障解决@FreeBSD

问题 在使用vm-bhyve虚拟机管理软件的时候&#xff0c;使用vm无法绑定网卡igb0 vm switch add public igb0 报错&#xff1a;/usr/local/sbin/vm: ERROR: failed to add member igb0 to the virtual switch public 解决 于是准备用原生ifconfig命令来绑定&#xff0c;结果…

【Go基础】快速入门

Go基础入门 用20%的时间学习常用80%的语法 官方网址&#xff08;下载安装/官方文档/官方类库&#xff09; Download Go binaries from https://go.dev/dl/Reference the official Go documentation https://go.dev/doc/See all the the Go packages https://pkg.go.dev/Access…

Linux基础指令及其作用之网络操作

网络操作pingifconfigeth0 接口 ip常用选项和命令 netstat示例输出解释 curl示例输出及解释 wget示例输出解释 网络操作 ping ping 命令用于测试网络连接的连通性和响应时间。它通过向目标主机发送 ICMP 回显请求&#xff08;echo request&#xff09;数据包&#xff0c;并等…

wpf 依赖属性的含义理解

依赖属性允许没有自己的字段&#xff0c;可以通过Binding绑定到其它对象的属性或者说数据源上&#xff0c;从而获得值。 缘由 由于控件有很多的属性&#xff0c;有属性就有字段的内存开销&#xff0c;但实际上对于一个控件&#xff0c;我们大多数只会使用其部分常用属性&#…

ConvNeXt(CVPR 2022)论文解读

paper&#xff1a;A ConvNet for the 2020s official implementation&#xff1a;https://github.com/facebookresearch/ConvNeXt third-party implementation&#xff1a;https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/convnext.py 背景 在…