第二十六章 linux-输入子系统二
文章目录
- 第二十六章 linux-输入子系统二
- 框架
- 三个重要结构体
- struct input_dev
- struct input_handler
- struct input_handle
框架
Linux系统支持的输入设备繁多,例如键盘、鼠标、触摸屏、手柄或者是一些输入设备像体感输入等等,Linux系统是如何管理如此之多的不同类型、不同原理、不同的输入信息的输入设备的呢?其实就是通过input输入子系统这套软件体系来完成的。从整体上来说,input输入子系统分为3层:上层(输入事件驱动层)、中层(输入核心层)、下层(输入设备驱动层),如下图:
-
input driver :主要实现对硬件设备的读写访问,中断设置,并把硬件产生的事件转换为核心层定义的规范提交给事件处理层。
input device driver 设备驱动程序
input event driver事件驱动程序
注意:事件驱动程穿是标准的,对所有的瑜入类都是可用的,所以,我们不需实现事件驱动,为内核里边已经支持所有的事件驱动;我们需实现的是输入设备备驱动程序 -
input core :承上启下。为设备驱动层提供了规范和接口;通知事件处理层对事件进行处理;
-
event handler :提供用户编程的接口(设备节点),并处理驱动层提交的数据处理。
三个重要结构体
struct input_dev
//表示的是一个具体的输入设备,描述设备能够产生什么数据
struct input_dev {
const char *name;//sysfs中给用户看的信息
const char *phys;
const char *uniq;
struct input_id id;
unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
/*evbit实际是一个位表,描述输入设备能够产生什么数据类型*/
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//能够表示768个bit,直接用24个long来表示,
//KEY_CNT=768 BITS_TO_LONGS=nr/32 768/32=24
//表示能够产生哪种按键
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)];
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;
unsigned int users;
bool going_away;
struct device dev;//继承device对象
struct list_head h_list;
struct list_head node;//表示节点
unsigned int num_vals;
unsigned int max_vals;
struct input_value *vals;
bool devres_managed;
};
struct input_handler
struct input_handler {
void *private;
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);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
bool legacy_minors;
int minor;
const char *name;
const struct input_device_id *id_table;
struct list_head h_list;
struct list_head node;
};
struct input_handle
struct input_handle {
void *private;
int open;
const char *name;
struct input_dev *dev;
struct input_handler *handler;
struct list_head d_node;
struct list_head h_node;
};
- input_dev代表底层的设备,所有设备的input_dev对象保存在一个全局的lnput_dev队列里。
- input_handler代表某类入设备的处理方法,比如说是专门处理入设备产成的Event〈事件〉,所有的input_handler存放在input_handler队里
- 一个input_dev可以有多个input_handler,
- lnput_handle用来关联某个input_dev和某个input_handler。每个input_handle都会生成一个文件节点,比如"/dev/input/event0、1、2、3…"。通过input handle可以找到对应的input handler和input_dev