Linux Input设备通用驱动框架

Input子系统架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
+-----------------------+
| 用户空间 |
|-----------------------|
| /dev/input/eventX | <- 应用程序通过读取这些设备文件获取输入事件
+-----------------------+

+-----------------------+
| Input 子系统 | <- 提供统一的输入接口
+-----------------------+

+-----------------------+
| Input 驱动 | <- 负责具体输入设备(如键盘、触摸屏)
+-----------------------+

+-----------------------+
| 硬件(键盘/鼠标等) |
+-----------------------+

Input驱动核心数据结构

struct input_dev (输入设备)

1
2
3
4
5
6
7
8
9
10
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 (输入事件)

1
2
3
4
5
6
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报告按键事件

1
2
3
4
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子系统当前一批输入事件已经结束,可以传递给用户空间

1
void input_sync(struct input_dev *dev);

Input设备注册

注册输入设备

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

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

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

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

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

函数原型:

1
2
3
4
5
6
7
8
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. 注册设备
1
2
3
4
5
ret = input_register_device(keyinputdev.inputdev);
if (ret) {
printk("reg input device failed\r\n");
return ret;
}

函数原型:

1
int input_register_device(struct input_dev *dev);

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

触发输入事件


Linux Input设备通用驱动框架
http://akichen891.github.io/2025/03/31/LinuxInput设备/
作者
Aki
发布于
2025年3月31日
更新于
2025年3月31日
许可协议