Input输入子系统分析_第1页
Input输入子系统分析_第2页
Input输入子系统分析_第3页
Input输入子系统分析_第4页
Input输入子系统分析_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、input子系统分析Jason一、概述在linux下,按键、触摸屏、鼠标等都可以利用input接口函数来实现设备驱动。1,linux输入子系统主要分三层: 驱动,输入CORE, 事件处理层。驱动根据CORE提供的接口,向上报告发生的按键动作。然后CORE根据驱动的类型,分派这个报告给对应的事件处理层进行处事。事件处理层把数据变化反应到设备模型的文件中(事件缓冲区)。并通知在这些设备模型文件上等待的进程。2,输入子系统在KERNEL初始化时被初始化。会创建所有类型输入输出设备的逻辑设备(及sysfs结点)。当硬件注册时,就会调用所有类型的input handler的connect函数,根据硬件注

2、册的结构来判断是否与自己相关,然后再创建一个具体的设备结点。3,驱动只负责的把输入设备注册到输入子系统中,然后输入子系统来创建对应的具体设备结点。而事件处理层,在初始化时,需要注册所一类设备的输入事件处理函数及相关接口4,一类input handler可以和多个硬件设备相关联,创建多个设备节点。而一个设备也可能与多个input handler相关联,创建多个设备节点。二、输入设备结构体1.input_dev 这是input设备基本的设备结构,每个input驱动程序中都必须分配初始化这样一个结构,成员比较多 代码路径 kernel/include/linux/input.h1. str

3、uct input_dev   2.     const char *name;       /设备名  3.     const char *phys;       /设备系统层的物理路径  4.     const&

4、#160;char *uniq;       /  5.     struct input_id id; /输入设备id 总线类型;厂商编号,产品id,产品版本  6.   7.     unsigned long evbitBITS_TO_LONGS(EV_CNT); /事件类型标志位  

5、;8.     unsigned long keybitBITS_TO_LONGS(KEY_CNT);   /键盘事件标志位  9.     unsigned long relbitBITS_TO_LONGS(REL_CNT);   /相对位移事件标志位  10.     unsigned long absbitBIT

6、S_TO_LONGS(ABS_CNT);   /绝对位移事件标志位  11.     unsigned long mscbitBITS_TO_LONGS(MSC_CNT);   /杂项事件标志位  12.     unsigned long ledbitBITS_TO_LONGS(LED_CNT);   /led指示灯标志位  

7、13.     unsigned long sndbitBITS_TO_LONGS(SND_CNT);   /声音事件  14.     unsigned long ffbitBITS_TO_LONGS(FF_CNT); /强制反馈事件  15.     unsigned long swbitBITS_TO_LONGS(SW_CNT);&

8、#160;/开关事件标志位  16.   17.     unsigned int hint_events_per_packet;  18.     unsigned int keycodemax;        /键盘码表大小  19.     unsigned in

9、t keycodesize;       /键盘码大小  20.     void *keycode;          /键盘码表指针  21.   22.     int (*setkeycode)(struct input_dev *

10、dev,unsigned int scancode, unsigned int keycode);   /设置键盘码  23.     int (*getkeycode)(struct input_dev *dev,unsigned int scancode, unsigned int *keycode);  /获取键盘码  24. &#

11、160;   int (*setkeycode_new)(struct input_dev *dev,const struct input_keymap_entry *ke,unsigned int *old_keycode);   25.     int (*getkeycode_new)(struct input_dev *dev,struct input_keymap_e

12、ntry *ke);  26.   27.     struct ff_device *ff;   /强制反馈设备  28.     unsigned int repeat_key;    /重复按键标志位  29.     struct timer_list 

13、;timer;    /定时器  30.     int repREP_CNT;       /重复次数  31.     struct input_mt_slot *mt;  32.     int mtsize;  33.   

14、;  int slot;  34.     struct input_absinfo *absinfo;  35.     unsigned long keyBITS_TO_LONGS(KEY_CNT);  /  36.     unsigned long ledBITS_TO_LONGS(LED_CNT);

15、  /  37.     unsigned long sndBITS_TO_LONGS(SND_CNT);  /  38.     unsigned long swBITS_TO_LONGS(SW_CNT);    /  39.   40.     int (*open

16、)(struct input_dev *dev);     /open方法  41.     void (*close)(struct input_dev *dev);   /close方法  42.     int (*flush)(struct input_dev *dev, struct fi

17、le *file);  43.     int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);  44.   45.     struct input_handle _rcu *grab;

18、60; 46.     spinlock_t event_lock;  47.     struct mutex mutex;  48.     unsigned int users;  49.     bool going_away;  50.    

19、60;bool sync;  51.     struct device dev;      /设备文件  52.     struct list_head    h_list; /input_handler处理器链表头  53.     struct lis

20、t_head    node;   /input_device设备链表头  54. ;  三、input_handler 输入处理器这是事件处理器的数据结构,代表一个事件处理器代码路径 kernel/include/linux/input.h1. struct input_handler   2.     void *private;  /私有数据  3.

21、    void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);    /事件处理  4.     bool (*filter)(struct input_handle *handle,

22、60;unsigned int type, unsigned int code, int value);   /过滤器  5.     bool (*match)(struct input_handler *handler, struct input_dev *dev);    /设备匹配  6.  

23、0;  int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); /设备连接  7.     void (*disconnect)(struct input_handle *handle);   &#

24、160;/设备断开连接  8.     void (*start)(struct input_handle *handle);  9.     const struct file_operations *fops; /输入操作函数集  10.     int minor;  /次设备号  11. &

25、#160;   const char *name;   /设备名  12.     const struct input_device_id *id_table; /输入设备 id表  13.     struct list_head    h_list; /input_handler处理

26、器链表头  14.     struct list_head    node;   /input_device设备链表头  15. ;  四、input_handle input_handle 结构体代表一个成功配对的input_dev和input_handler代码路径 kernel/include/linux/input.hstruct input_handle  1.  

27、   void *private; /每个配对的事件处理器都会分配一个对应的设备结构,如evdev事件处理器的evdev结构,注意这个结构与设备驱动层的input_dev不同,初始化handle时,保存到这里。 2.     int open; /打开标志,每个input_handle 打开后才能操作,这个一般通过事件处理器的open方法间接设置 3.     const char *name; 

28、4.     struct input_dev *dev; /关联的input_dev结构 5.     struct input_handler *handler; /关联的input_handler结构 6.     struct list_head d_node; /input_handle通过d_node连接到了input_dev上的h_list链表上 7.   

29、60; struct list_head h_node; /input_handle通过h_node连接到了input_handler的h_list链表上 8. ; 五、三个数据结构之间的关系input_dev 是硬件驱动层,代表一个input设备input_handler 是事件处理层,代表一个事件处理器input_handle 个人认为属于核心层,代表一个配对的input设备与input事件处理器input_dev 通过全局的input_dev_list链接在一起。设备注册的时候实现这个操作。input_handler 通过全局的input_hand

30、ler_list链接在一起。事件处理器注册的时候实现这个操作(事件处理器一般内核自带,一般不需要我们来写)input_hande 没有一个全局的链表,它注册的时候将自己分别挂在了input_dev 和 input_handler 的h_list上了。通过input_dev 和input_handler就可以找到input_handle在设备注册和事件处理器,注册的时候都要进行配对工作,配对后就会实现链接。通过input_handle也可以找到input_dev和input_handler。     我们可以看到,input_device和inp

31、ut_handler中都有一个h_list,而input_handle拥有指向input_dev和input_handler的指针,也就是说input_handle是用来关联input_dev和input_handler的。那么为什么一个input_device和input_handler中拥有的是h_list而不是一个handle呢?因为一个device可能对应多个handler,而一个handler也不能只处理一个device,比如说一个鼠标,它可以对应even handler,也可以对应mouse handler,因此当其注册时与系统中的handler进行匹配,就有可能产生两个实例,一个

32、是evdev,另一个是mousedev,而任何一个实例中都只有一个handle。至于以何种方式来传递事件,就由用户程序打开哪个实例来决定。后面一个情况很容易理解,一个事件驱动不能只为一个甚至一种设备服务,系统中可能有多种设备都能使用这类handler,比如event handler就可以匹配所有的设备。在input子系统中,有8种事件驱动,每种事件驱动最多可以对应32个设备,因此dev实例总数最多可以达到256个。六、输入系统初始化代码路径 kernel/drivers/input/input.c9. static int _init input_init(voi

33、d)  10.   11.     int err;  12.   13.     err = class_register(&input_class); /注册类 创建"/sys/input"   14.     if (err)   15. 

34、60;       printk(KERN_ERR "input: unable to register input_dev classn");  16.         return err;  17.       18.   19. &

35、#160;   err = input_proc_init();    /初始化"/proc/bus/input"接口  20.     if (err)  21.         goto fail1;  22.   23.    

36、60;err = register_chrdev(INPUT_MAJOR, "input", &input_fops);   /注册所有输入字符设备,并捆绑input_fops  24.     if (err)   25.         printk(KERN_ERR "input: u

37、nable to register char major %d", INPUT_MAJOR);  26.         goto fail2;  27.       28.   29.     return 0;  30.   31.  fail2: input_proc_e

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论