input子系统学习二:数据结构

1.input_dev结构体   是硬件驱动层,代表一个input设备

 1 struct input_dev {
 2     const char *name;
 3     const char *phys;
 4     const char *uniq;
 5     struct input_id id;  //与input_handler匹配用的id
 6 
 7    unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//支持所有的事件类型
 8    unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//支持按键事件
 9    unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//支持相对位移事件
10    unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];//支持绝对位移事件
11    unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//支持其它事件
12    unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//支持led事件
13    unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//支持声音事件
14    unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//支持受力事件
15    unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//支持开关机时间
16 
17     unsigned int keycodemax;
18     unsigned int keycodesize;
19     void *keycode;
20     int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
21     int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
22 
23     struct ff_device *ff;
24 
25     unsigned int repeat_key;//最近一次按键值
26     struct timer_list timer;
27 
28     int sync;
29 
30     int abs[ABS_MAX + 1];
31     int rep[REP_MAX + 1];
32 
33     unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反应设备当前的按键状态
34     unsigned long led[BITS_TO_LONGS(LED_CNT)];//反应设备当前的led状态
35     unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反应设备当前的声音输入状态
36     unsigned long sw[BITS_TO_LONGS(SW_CNT)];//反应设备当前的开关状态
37 
38     int absmax[ABS_MAX + 1];
39     int absmin[ABS_MAX + 1];
40     int absfuzz[ABS_MAX + 1];
41     int absflat[ABS_MAX + 1];
42     int absres[ABS_MAX + 1];
43 
44     int (*open)(struct input_dev *dev);//第一次打开设备时调用,初始化设备
45     void (*close)(struct input_dev *dev);//最后一个应用程序释放设备时用,关闭设备
46     int (*flush)(struct input_dev *dev, struct file *file);//用于处理传递给设备的事件,如led或声音事件
47     int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
48 
49     struct input_handle *grab;//当前占有该设备的input_handle
50 
51     spinlock_t event_lock;
52     struct mutex mutex;
53 
54     unsigned int users;//打开该设备的用户数量(input_handlers)
55     bool going_away;
56 
57     struct device dev;
58 
59     struct list_head    h_list;//该链表头用于链接此input_dev所关联的input_handle
60     struct list_head    node;//用于将此input_dev链接到input_dev_list
61 };
View Code

2. input_handler结构体  是事件处理层,代表一个事件处理器

 1 struct input_handler {
 2 
 3     void *private;
 4 
 5     void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);//event用于处理事件
 6     int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);//connect用于建立handler和device的联系
 7     void (*disconnect)(struct input_handle *handle);//disconnect用于解除handler和device的联系
 8     void (*start)(struct input_handle *handle);
 9 
10     const struct file_operations *fops;
11     int minor;
12     const char *name;
13 
14     const struct input_device_id *id_table;//用于和input_dev匹配
15     const struct input_device_id *blacklist;
16 
17     struct list_head    h_list;//用于链接和此input_hanler相关的input_handle
18     struct list_head    node;//用于将该input_handler链入input_handler_list
19 };
View Code

3. input_handle 结构体 个人认为属于核心层,代表一个配对的input设备与input事件处理器

 1 struct input_handle {
 2 
 3     void *private;
 4 
 5     int open;//记录设备的打开次数(有多少个应用程序访问设备)
 6     const char *name;
 7 
 8     struct input_dev *dev;//指向所属的device
 9     struct input_handler *handler;//指向所属的handler
10 
11     struct list_head    d_node;//用于将此input_handle链入所属input_dev的h_list链表
12     struct list_head    h_node;//用于将此input_handle链入所属input_handler的h_list链表
13 };
View Code

4. evdev

 1 struct evdev {
 2     int exist;
 3     int open;
 4     int minor;
 5     struct input_handle handle;
 6     wait_queue_head_t wait;
 7     struct evdev_client *grab;
 8     struct list_head client_list;
 9     spinlock_t client_lock; /* protects client_list */
10     struct mutex mutex;
11     struct device dev;
12 };
View Code

5. evdev_client

1 struct evdev_client {
2     struct input_event buffer[EVDEV_BUFFER_SIZE];
3     int head;
4     int tail;
5     spinlock_t buffer_lock; /* protects access to buffer, head and tail */
6     struct fasync_struct *fasync;
7     struct evdev *evdev;
8     struct list_head node;
9 };
View Code

 

4. 五个数据结构之间的关系

  struct evdev        当某个struct input_dev和evdev_handler匹配成功后就新建一个struct evdev,看到这里是不是有点和  
                                struct input_handle产生的时间一致呀,起始该结构体内部就包含一个struct input_handle;不过结合了  
                                一些其他信息,可以把它看做是struct input_handle的升级版。  
      struct evdev_client     主要跟应用程序有关.每打开一次设备就新建一个struct evdev_client,里面保存了应用程序要读取的数据  
                                      以及数据的位置。  
     input_dev 通过全局的input_dev_list链接在一起。设备注册的时候实现这个操作。
     input_handler 通过全局的input_handler_list链接在一起。事件处理器注册的时候实现这个操作(事件处理器一般内核自带,一般不需要我们来写)

     input_hande 没有一个全局的链表,它注册的时候将自己分别挂在了input_dev 和 input_handler 的h_list上了。通过input_dev 和input_handler就可以找到

input_handle 在设备注册和事件处理器, 注册的时候都要进行配对工作,配对后就会实现链接。通过input_handle也可以找到input_dev和       input_handler。

我们可以看到,input_device和input_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进行匹配,就有可能产生两个实例,一个是evdev,另一个是mousedev,而任何一个实例中都只有一个handle。至于以何种方式来传递事件,就由用户程序打开哪个实例来决定。后面一个情况很容易理解,一个事件驱动不能只为一个甚至一种设备服务,系统中可能有多种设备都能使用这类handler,比如event handler就可以匹配所有的设备。在input子系统中,有8种事件驱动,每种事件驱动最多可以对应32个设备,因此dev实例总数最多可以达到256个。

 

         

        

 

转载于:https://www.cnblogs.com/jetli-/p/5213729.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值