目录:
输入子系统的作用与框架
输入子系统的编程方式
一、输入子系统的作用与框架
1、输入设备
按键、鼠标、触摸屏:gt811,ft56xx
有多个输入设备需要驱动的时候,假如不考虑输入子系统
a, gt811
注册设备号,创建设备文件,硬件初始化,实现fop,阻塞
b, ft56xx
注册设备号,创建设备文件,硬件初始化,实现fop,阻塞
多个输入设备有共同点:
获取到数据(操作硬件),上报给用户(xxx_read, copy_to_user, 阻塞)
差异化 通用
通用的部分内核会完成,差异化的代码由开发人员编写
由此对于不同的、分散的输入设备进行统一的驱动,将其设计成输入子系统
2、输入子系统的作用
1)兼容所有输入设备
统一了物理形态各异的相似的输入设备的处理功能。例如,各种鼠标,不论PS/2、USB、还是蓝牙,都被同样处理。
2)统一的应用操作接口
提供了用于分发输入报告给用户应用程序的简单的事件(event)接口。你的驱动不必创建、管理/dev节点以及相关的访问方法。因此它能够很方便的调用输入API以发送鼠标移动、键盘按键,或触摸事件给用户空间。
3)统一的编程驱动方法
抽取出了输入驱动的通用部分,简化了驱动,并提供了一致性。例如,输入子系统提供了一个底层驱动(成为serio)的集合,支持对串口和键盘控制器等硬件输入的访问
输入子系统使得应用编程人员和驱动编程人员编程的时候变得简单统一。
3、输入子系统框架
linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:
应用层
--------------------------------------------------------------------------------------------------------------------------
事件处理层:数据处理者
完成fop:实现xxx_read(), xxx_open
将数据交给用户:数据从input device层
不知道具体数据是什么,只知道把数据给用户
-----------------------------------------------------------------------------------------------------------------------------
核心层:承上启下
为驱动层提供输入设备注册与操作接口,如:input_register_device;通知事件处理层对事件 进行处理;在/Proc下产生相应的设备信息。设备驱动层只要关心如何驱动硬件并获得硬件数据,然后调用核心层提供的接口,核心层会自动把数据提交给事件处理层。
------------------------------------------------------------------------------------------------------------------------------
设备驱动层:数据采集者
抽象出一个对象,描述输入设备信息
初始化输入设备硬件,获取到数据
知道具体的数据是什么,但是不知道数据如何给用户
------------------------------------------------------------------------------------------------------------------------------
硬件层:mouse,ts, keybaord,joystick
(编程主要在设备驱动层)
二、输入子系统编程方式
1、最简单的输入设备驱动程序
实现最简单的输入设备注册
1 #include <linux/module.h> 2 #include <linux/init.h> 3 #include <linux/input.h> 4 5 struct input_dev *inputdev; 6 7 static int __init simple_input_init(void) 8 { 9 int ret; 10 11 //编写输入子系统代码 12 /* 13 * 1、分配一个input device对象 14 * 2、初始化input device对象 15 * 3、注册input device 对象 16 */ 17 18 inputdev = input_allocate_device(); 19 if(inputdev == NULL) 20 { 21 printk(KERN_ERR"input_allocate_device error\n"); 22 return -ENOMEM; 23 } 24 25 //使当前设备能够产生按键数据 26 __set_bit(EV_KEY, inputdev->evbit); 27 //表示当前设备能产生power按键 28 __set_bit(KEY_POWER, inputdev->keybit); 29 30 ret = input_register_device(inputdev); 31 if(ret != 0) 32 { 33 printk(KERN_ERR"input_register_device error\n"); 34 goto err_0; 35 return ret; 36 } 37 38 return 0; 39 40 err_0: 41 input_free_device(inputdev); 42 return ret; 43 } 44 45 static void __exit simple_input_exit(void) 46 { 47 input_unregister_device(inputdev); 48 input_free_device(inputdev); 49 } 50 51 module_init(simple_input_init); 52 module_exit(simple_input_exit); 53 MODULE_LICENSE("GPL");