input子系统介绍
输入子系统研究的对象是处理和管理输入设备,它的目标是提供一个统一的接口和框架,使驱动开发人员能够更轻松地编写和管理输入设备的驱动程序。
输入设备可以是各种外部设备,如键盘、鼠标、触摸屏、游戏手柄等。输入子系统的设计目的是为了提供一种标准化的方式来处理这些设备,并将它们的输入数据传递给上层应用程序或其他部分。
通过提供统一的接口和框架,输入子系统简化了驱动程序的开发和维护过程。它定义了通用的数据结构和函数,使得驱动程序可以以一致的方式与不同类型的输入设备进行交互。这样,驱动开发人员可以更加专注于设备特定的细节,而不需要处理输入设备的低级细节和复杂性。
一、输入子系统框架
APP:
驱动层:
input_handler层:linux-5.4.31/drivers/input/evdev.c
//数据处理层,知道数据如何传递给用户空间,但是不知道数据怎么产生的
//实现了下面的工作:
1.创建设备节点
2.实现了file_operation函数
input_core层:linux-5.4.31/drivers/input/input.c
//input核心层,维护input子系统的框架(用来匹配),对上下两层提供注册接口
//实现了下面的工作:
1.申请设备号
2.创建类
input_dev层:
//input设备层,每一个输入设备对应一个input_dev,开发人员自己写代码
//知道数据怎么产生,但是不知道如何把数据给到用户
//实现了下面的工作:
1.硬件初始化
2.上报数据
二、使用input子系统
需要在内核菜单里个勾选上位置在
-> Device Drivers -> Input device support -> Generic input layer (needed for keyboard, mouse, …) (INPUT [=y])
选中以上的选项,就可以确保evdev.c(input_handler层)和input.c(input_core层)被编译到Linux内核,即内核支持input子系统
三、input子系统编程思路
1、创建输入设备结构体 dev
struct device_key {
struct input_dev * dev;
};
2、创建平台设备处理函数
platform_device_function(struct platform_device * pdev)
{
//1.创建全局的结构体对象
key = kzalloc(sizeof(struct device_key ), GFP_KERNEL);
//2.创建input_dev结构体对象
key->dev = devm_input_allocate_device(&pdev->dev);
//3.初始化input_dev
key->dev->name = "device_key ";
//4.注册input_dev
input_register_device(key->dev);
//5.硬件初始化
key_list[i].gpio = devm_gpiod_get_index(&pdev->dev, "key", i, \
GPIOD_ASIS); //获取按键寄存器的相应位置
irq_no = gpiod_to_irq(key_list[i].gpio);//获取按键GPIO的中断号
request_irq(irq_no, key_drv_irq_handler, key_list[i].flag,\
key_list[i].name, &key_list[i]); //注册中断处理函数
}
//创建中断处理函数
irqreturn_t drv_handler(int irq_no, void * data)
{
input_event(dev, EV_KEY, KEY_A, 0);
input_sync(dev);
}