从三个基础结构到事件上报流程
声明:这篇博客大部分来自
https://blog.csdn.net/u014545515/article/details/53507567?utm_source=blogxgwz1
我跟着这篇博客的思路一路下来,觉得非常有收货,也写入自己的感悟。
广泛,并且深入
-沉默犀牛
三个层级
事件处理层:evdev.c 、mousedev.c
核心层:input.c
设备驱动层:touchscreen、mouse
事件处理层:通过核心层的API获取输入事件上报的数据,定义API与应用层交互
核心层:为事件处理层和设备驱动层提供接口API
设备驱动层:采集输入设备的数据信息,通过核心层提供的API上报数据
基础数据结构
struct input_dev:会在具体input driver 层中被填充
struct input_handle:会在event handler层和input driver层注册设备时通过input_dev或input_handler间接调用
struct input_handler:会在event handler层(如evdev.c)中被实例化
input_dev
struct input_dev {
const char *name; /*导出到用户空间的相关信息,在sys文件可以看到*/
const char *phys;
const char *uniq;
struct input_id id; /*与input_handler匹配用的id*/
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); /*LED事件*/
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); //用于处理传递给设备的事件,如LED事件
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
struct input_handle __rcu *grab; //当前占有该设备的input_handle
spinlock_t event_lock;
struct mutex mutex;
unsigned int users;
bool going_away;
struct device dev;
struct list_head h_list; //该链表头用于链接此input_dev所关联的input_handle
struct list_head node; //用于将此input_dev链接到input_dev_list
unsigned int num_vals;
unsigned int max_vals;
struct input_value *vals;
bool devres_managed;
};
input_handler
struct input_handler {
void *private;
/*event用于处理事件*/
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
void (*events)(struct input_handle *handle,
const struct input_value *vals, unsigned int count);
bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*match)(struct input_handler *handler, struct input_dev *dev);
/*connect用于建立handler和device的联系*/
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle); /*disconnect用于解除handler和device的联系*/
void (*start)(struct input_handle *handle);
void (*start)(struct input