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

input_handler和input_dev详解

文章目录

    • 🧩 背景:Linux 输入子系统结构图
    • 1️⃣ struct input\_dev — 表示一个输入设备
      • 🧷 关键字段简要说明:
      • 📌 设备驱动中怎么使用它?
    • 2️⃣ struct input\_handler — 表示一个处理 input\_dev 的 handler(协议驱动)
      • 🧷 关键字段简要说明:
      • 📌 它的作用是什么?
    • 3️⃣ struct input\_handle — input\_dev 与 input\_handler 的桥梁
    • 🔗 它们之间的协作流程(简化)
    • 🧪 举个实际场景:evdev handler 处理触摸屏 input\_dev
    • 🧠 总结



🧩 背景:Linux 输入子系统结构图

Linux 输入子系统主要由以下几部分组成:

     +----------------+|  input_event   | ← 用户空间读取设备事件+----------------+↑+----------------+| input_handler  | ← 处理 input_dev 事件(例如 evdev, mousedev)+----------------+↑+----------------+|  input_dev     | ← 设备驱动注册的输入设备+----------------+

input_dev 由设备驱动注册,
input_handler 由上层“协议”驱动注册(比如 evdev/mousedev/joydev)
两者配对后,用户程序就可以通过 /dev/input/eventX 获取事件。


1️⃣ struct input_dev — 表示一个输入设备

该结构体定义于 <linux/input.h>,是设备驱动(比如触摸屏、按键、鼠标)注册输入设备时要填充的核心结构体

🧷 关键字段简要说明:

struct input_dev {const char *name;               // 设备名称const char *phys;               // 物理路径(例如 "usb-0000:00:1d.0-1/input0")const char *uniq;               // 唯一标识(可选)struct input_id id;             // 设备ID信息(vendor, product, version等)unsigned long evbit[BITS_TO_LONGS(EV_CNT)];   // 支持的事件类型(比如按键、相对坐标等)unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; // 支持的按键种类(比如 KEY_A、KEY_B)unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; // 支持的相对坐标事件(比如鼠标移动)unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; // 支持的绝对坐标事件(比如触摸屏)struct input_mt *mt;            // 多点触控支持int (*open)(struct input_dev *dev);      // 当 handler 打开时调用void (*close)(struct input_dev *dev);    // 当 handler 关闭时调用struct input_dev_poller *poller; // 轮询器支持(可选)void *private;                  // 设备私有数据...
};

📌 设备驱动中怎么使用它?

  • 初始化 input_dev,设置支持的事件类型、设备 ID、名字等;
  • 使用 input_register_device() 注册;
  • 使用 input_report_key()input_sync() 上报事件。

举例:

input_dev->name = "My Button Device";
set_bit(EV_KEY, input_dev->evbit);
set_bit(KEY_ENTER, input_dev->keybit);input_register_device(input_dev);

2️⃣ struct input_handler — 表示一个处理 input_dev 的 handler(协议驱动)

input_handler 结构体由上层协议驱动(比如 evdev、mousedev)注册,用于接收输入事件并提供给用户空间。

🧷 关键字段简要说明:

struct input_handler {const char *name;  // 处理器名称(如 "evdev")bool (*match)(struct input_handler *, struct input_dev *); // 判断是否匹配某个 input_devint (*connect)(struct input_handler *, struct input_dev *, const struct input_device_id *);void (*disconnect)(struct input_handle *);void (*start)(struct input_handle *); // 可选const struct input_device_id *id_table; // 支持的设备类型表struct list_head h_list;               // handler 链表节点struct list_head node;                 // 全局 handler 链表...
};

📌 它的作用是什么?

  • 系统启动时,协议驱动注册 input_handler
  • 当驱动注册一个 input_dev 后,input core 会尝试用每个 handler 去 match 它;
  • 匹配成功后,调用 connect() 绑定,生成 /dev/input/eventX 节点;
  • 用户空间可以通过 read /dev/input/eventX 获取事件。

3️⃣ struct input_handle — input_dev 与 input_handler 的桥梁

handlerdev 匹配并 connect 成功之后,会创建 input_handle 结构体来维护它们之间的绑定关系。

struct input_handle {void *private;                 // 私有数据int open;                      // 被打开次数const char *name;             // 名称struct input_dev *dev;        // 指向 input_devstruct input_handler *handler;// 指向 input_handlerstruct list_head d_node;      // 挂到 dev 的 handle 链表struct list_head h_node;      // 挂到 handler 的 handle 链表
};

🔗 它们之间的协作流程(简化)

【驱动层】
1. 驱动注册 input_dev(input_register_device)【协议层】
2. handler 注册 input_handler(input_register_handler)【input core】
3. 自动匹配 input_handler 与 input_dev
4. 成功后调用 handler->connect()
5. 创建 input_handle → 建立 dev 和 handler 的关联
6. 用户可通过 /dev/input/eventX 读取事件

🧪 举个实际场景:evdev handler 处理触摸屏 input_dev

  • 驱动注册了一个 input_dev,支持 EV_ABS(ABS_X、ABS_Y);
  • evdev 的 handler->match() 成功匹配;
  • handler->connect() 被调用,创建 input_handle;
  • evdev 创建 /dev/input/eventX
  • 用户程序可以通过这个节点读到触摸坐标事件。

🧠 总结

结构体定义者作用
input_dev设备驱动描述一个输入设备
input_handler协议驱动匹配、处理 input_dev
input_handleinput core管理 handler 和 dev 的连接关系

input_dev 是设备,input_handler 是处理器,input_handle 是它们的桥梁。


http://www.dtcms.com/a/301166.html

相关文章:

  • 【AI阅读】20250717阅读输入
  • 深度学习在计算机视觉中的应用:对象检测
  • C++ auto 类型推导
  • Netty中 ? extends Future<? super V>这种的写法的理解
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 73(题目+回答)
  • PDF文件被加密限制怎么办?专业级解除方案分享
  • mysql 快速上手
  • FFmpeg——参数详解
  • 3.JDK+JRE组件构成与协作
  • LeetCode 923.多重三数之和
  • 【AI论文】WebShaper:通过信息寻求形式化实现主动式数据合成
  • CIFAR100数据集实测-基于 AlexNet模型的压缩/Bagging/Boosting 探索
  • 创建的springboot工程java文件夹下还是文件夹而不是包
  • 大数据之路:阿里巴巴大数据实践——大数据领域建模综述
  • 卷积神经网络研讨
  • haproxy七层代理(知识点+相关实验部署)
  • 【奔跑吧!Linux 内核(第二版)】第5章:内核模块
  • 关系与逻辑运算 —— 寄存器操作的 “入门钥匙”
  • Linux: 调试器gdb/cgdb
  • 第六章 JavaScript 互操(2).NET调用JS
  • K-近邻算法
  • MPLS LDP(概念)
  • 20250707-2-Kubernetes 网络-Ingress暴露应用(http与https)_笔记
  • Flink窗口:解锁流计算的秘密武器
  • JavaEE初阶第十二期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(十)
  • KingbaseES聚焦产品上线
  • 卫星图像语义分割与区域相似度比较研究
  • 顺序表算法题
  • 【自动化运维神器Ansible】Ansible常用模块之hostname模块详解
  • Qt C++动态库SDK在Visual Studio 2022使用(C++/C#版本)