584 字
3 分钟
Linux Input设备通用驱动框架

Input子系统架构#

+-----------------------+
| 用户空间 |
|-----------------------|
| /dev/input/eventX | <- 应用程序通过读取这些设备文件获取输入事件
+-----------------------+
+-----------------------+
| Input 子系统 | <- 提供统一的输入接口
+-----------------------+
+-----------------------+
| Input 驱动 | <- 负责具体输入设备(如键盘、触摸屏)
+-----------------------+
+-----------------------+
| 硬件(键盘/鼠标等) |
+-----------------------+

Input驱动核心数据结构#

struct input_dev (输入设备)#

struct input_dev {
const char *name; // 设备名称
unsigned long evbit[EV_MAX]; // 支持的事件类型 (如键盘按键、鼠标移动)
unsigned long keybit[KEY_MAX]; // 支持的按键
unsigned long relbit[REL_MAX]; // 相对坐标事件(鼠标)
unsigned long absbit[ABS_MAX]; // 绝对坐标事件(触摸屏)
struct input_mt *mt; // 多点触控支持
int (*open)(struct input_dev *dev); // 设备打开回调
int (*close)(struct input_dev *dev); // 设备关闭回调
};

struct input_event (输入事件)#

struct input_event {
struct timeval time; // 时间戳
__u16 type; // 事件类型 (EV_KEY, EV_REL, EV_ABS)
__u16 code; // 事件代码 (键值或坐标轴)
__s32 value; // 事件值 (按键按下/释放,坐标值等)
};

struct input_handler (输入处理程序)#

input_report_key#

用于向kernel报告按键事件

void input_report_key(struct input_dev *dev, unsigned int code, int value);
code:按键的键值,如KEY_A表示A键
value: 1:按下,0:释放,2:保持按下

键值在include/uapi/linux/input-event-codes.h中定义

input_sync()#

用于同步事件,告知input子系统当前一批输入事件已经结束,可以传递给用户空间

void input_sync(struct input_dev *dev);

Input设备注册#

注册输入设备#

  1. 声明input_dev 一般在设备结构体中设置
struct xxx_dev {
...
struct input_dev *inputdev;
}
  1. 申请设备
keyinputdev.inputdev = input_allocate_device();
keyinputdev.inputdev->name = KEYINPUT_NAME;

input_allocate_device()用于申请并初始化一个input_dev结构体

  1. 设置事件类型
keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);

evbit代表设备支持的事件类型:

  • BIT_MASK(EV_KEY):支持按键事件
  • BIT_MASK(EV_REP):支持按键重复,长按时不断触发
  1. 绑定按键 告知input子系统这个设备支持某个按键
input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0);

函数原型:

void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);
type:事件类型
code:具体的按键/轴/开关代码,包括:
EV_KEY 按键事件
EV_REL 相对轴事件(鼠标移动、滚轮)
EV_ABS 绝对轴事件(触摸屏、操纵杆)
EV_SW 开关事件(外设插入检测)
  1. 注册设备
ret = input_register_device(keyinputdev.inputdev);
if (ret) {
printk("reg input device failed\r\n");
return ret;
}

函数原型:

int input_register_device(struct input_dev *dev);

卸载时使用input_unregister_device(keyinputdev.inputdev)input_free_device(keyinputdev.inputdev)释放input设备

触发输入事件#

Linux Input设备通用驱动框架
https://arkmostima.pages.dev/posts/linuxinput设备/
作者
Aki
发布于
2025-03-31
许可协议
CC BY-NC-SA 4.0