★什么是Linux输入子系统?为什么引入Linux输入子系统?html
Linux输入子系统是为多种不一样的输入设备提供一种统一的机制,将它们归属到统一架构下面。在输入子系统之前,输入设备(鼠标、键盘)都是采用字符设备或者混杂设备进行处理。所以就会产生一个问题,如何将硬件不一样、类型不一样的输入设备进行统一的处理,才有了后面的Linux输入子系统。node
★Linux输入子系统的层次结构编程
Linux输入子系统分为三个层次:设备驱动层、核心层、事件处理层。一个输入事件(鼠标产生的事件)会经过设备驱动层、核心层、事件处理层、到达用户空间最终到达应用程序。数组
(注:图片来源http://www.cnblogs.com/cute/archive/2011/08/30/2159305.html)数据结构
★Linux输入子系统的分层架构
(注:图片来源http://www.cnblogs.com/cute/archive/2011/08/30/2159305.html)函数
★Linux输入子系统之设备驱动层ui
◇做用google
驱动层主要负责与硬件打交道。对硬件设备的访问,中断设置,将硬件产生的事件转换为核心层定义的规范提交给事件处理层。编码
◇重要的数据结构
输入设备数据结构:input_dev
struct input_dev { const char *name;//提供给用户的输入设备的名称 const char *phys;//提供给编程者的设备节点的名称 const char *uniq;//指定惟一的ID号 struct input_id id;//输入设备标识ID,用于和事件处理层进行匹配 /**BITS_TO_LONGS的做用:求一个数是几个long的长度**/ unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//记录设备支持的事件类型 //下面是每种类型支持的编码 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//记录设备支持的按键类型 unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//记录设备支持的相对坐标 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];//记录设备支持的绝对坐标 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//记录设备支持的其余功能 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//记录设备支持的指示灯 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//记录设备支持的声音或警报 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//记录设备支持的做用力功能 unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//记录设备支持的开关功能 unsigned int hint_events_per_packet; unsigned int keycodemax; //设备支持的最大按键值个数 unsigned int keycodesize;//每一个按键的字节大小 void *keycode;//指向按键值数组的首地址 int (*setkeycode)(struct input_dev *dev, const struct input_keymap_entry *ke, unsigned int *old_keycode); //设置按键值 int (*getkeycode)(struct input_dev *dev, struct input_keymap_entry *ke);//修改按键值 struct ff_device *ff; unsigned int repeat_key; //重复按键的键值 struct timer_list timer; //设置当有连击时的延时定时器 int rep[REP_CNT]; //重复记录按键的参数值 struct input_mt *mt; struct input_absinfo *absinfo; unsigned long key[BITS_TO_LONGS(KEY_CNT)]; //按键的状态 unsigned long led[BITS_TO_LONGS(LED_CNT)]; //LED的状态 unsigned long snd[BITS_TO_LONGS(SND_CNT)]; //声音的状态 unsigned long sw[BITS_TO_LONGS(SW_CNT)]; //开关的状态 int (*open)(struct input_dev *dev); //输入设备打开函数 void (*close)(struct input_dev *dev); //输入设备关闭函数 int (*flush)(struct input_dev *dev, struct file *file); //输入设备断开后刷新函数 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); //事件处理 struct input_handle __rcu *grab; spinlock_t event_lock; struct mutex mutex; //用于open、close函数的连续访问互斥 unsigned int users; //设备使用计数器 bool going_away; struct device dev; struct list_head h_list; //handle列表 struct list_head node; //input_dev链表 unsigned int num_vals; unsigned int max_vals; struct input_value *vals; bool devres_managed; };◇重要的函数
分配与注册一个输入设备
分配:
Struct input_dev *input_allocate_device*(void);//分配一个输入设备结构体的指针。
注册:
int input_register_device(struct input_dev *dev);
这个函数把dev输入设备挂在输入设备链表中,而且通知事件处理层调用connect函数完成设备和事件处理的绑定,
当用户打开设备时,便可以调用到相应的事件处理接口得到硬件上报的数据了。
◇事件的支持
对于一个设备驱动,要使用set_bit()函数来告诉输入子系统它支持哪些事件,例如:
set_bit(nuc970_keycode[i], input_kp_dev->keybit);设置按键的类型。在input_dev结构体下有两个数组 unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//支持的事件类型 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//支持的按键类型事件类型:
#define EV_SYN 0x00 //同步事件 #define EV_KEY 0x01 //按键事件 #define EV_REL 0x02 //相对坐标 #define EV_ABS 0x03 //绝对坐标 #define EV_MSC 0x04 //其余 #define EV_SW 0x05 //开关 #define EV_LED 0x11 //按键/设备灯 #define EV_SND 0x12 //声音 #define EV_REP 0x14 //重复 #define EV_FF 0x15 //力反馈 #define EV_PWR 0x16 //电源 #define EV_FF_STATUS 0x17 //力反馈状态 #define EV_MAX 0x1f //事件类型最大个数和提供位掩码支持 #define EV_CNT (EV_MAX+1)◇事件的报告
Void input_report_key(struct input_dev *dev,unsigned int code, int value) //报告键值 Void input_report_rel(struct input_dev *dev,unsigned int code, int value) //报告相对坐标 Void input_report_abs(struct input_dev *dev,unsigned int code, int value) //报告绝对坐标 Void input_sync(struct input_dev *dev);//报告同步事件◇释放与注销设备
Void input_free_device(struct input_dev *dev); Void input_unregister_device(struct input_dev *);参考资料:
http://7071976.blog.51cto.com/7061976/1398175
http://blog.csdn.net/voice_shen/article/details/7005681
http://blog.csdn.net/ielife/article/details/7798952
http://www.chengxuyuans.com/Linux/66974.html
https://sites.google.com/site/rgbbones2/inputsubsystem
http://blog.chinaunix.net/uid/23770712/list/2.html
http://www.cnblogs.com/cute/archive/2011/08/30/2159305.html