input子系统介绍
linux内核为了能够处理各种不同类型的输入设备,比如: 触摸屏 ,鼠标 , 键盘 , 操纵杆等设备 ,设计并实现了linux 输入子系统 ,它为驱动和应用提供了统一的接口函数,方便实现各种输入设备的驱动。
input子系统架构
(1)驱动层功能 :负责和底层的硬件设备打交道,将底层硬件设备对用户输入的响应转换为标准的输入事件以后再向上发送给输入子系统核心层。
(2)input系统核心层 :由driver/input/input.c及相关头文件实现,它对下提供了设备驱动层的接口,对上提供了事件处理层的编程接口。
(3)事件处理层 :将硬件设备上报的事件分发到用户空间和内核。
重要结构体
input_dev//输入设备struct input_dev { const char *name; //设备名称 const char *phys; //设备的物理路径 const char *uniq; //唯一id struct input_id id; //输入id unsigned long propbit[bits_to_longs(input_prop_cnt)]; //设备属性 //所支持的input事件,(键盘, 按键,坐标等) 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)]; 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; //设备 struct list_head h_list; struct list_head node; unsigned int num_vals; unsigned int max_vals; struct input_value *vals;};input_dev代表了一个输入设备,结构体里面就是保存了输入设备的信息,以及不同输入设备的不同事件。
api函数
//分配一个输入设备struct input_dev *input_allocate_device(void)//释放输入设备void input_free_device(struct input_dev *dev)//注册输入设备到输入核心层int input_register_device(struct input_dev *dev)//注销输入设备void input_unregister_device(struct input_dev *dev)/*报告输入事件参数说明: dev: 产生事件的设备 type: 事件的类型 code:事件码 value:事件的值*/void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)//报告按键事件,内部调用input_event 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) //用来设置设备所产生的事件以及上报的按键值#define set_bit(nr,p) atomic_bitop(set_bit,nr,p)#define clear_bit(nr,p) atomic_bitop(clear_bit,nr,p)输入设备事件类型
ev_syn 0x00 //同步事件ev_key 0x01 //按键事件ev_rel 0x02 //相对坐标ev_abs 0x03 //绝对坐标ev_msc 0x04 //其它ev_led 0x11 //ledev_snd 0x12 //声音ev_rep 0x14 //repeatev_ff 0x15 //力反馈ev_pwr //电源ev_ff_status //状态每个事件类型下面会有一些事件码(event codes),它会更精准的描述事件类型。
总结
输入设备驱动的内容并不多,主要还是要对设备的工作原理有深入的了解,才能编写对应驱动。
E拆解:三星Galaxy A80日本元器件数量占比超七成
自动驾驶汽车榜单出炉,中国仍排20名,新加坡却位居榜首
选择网关时考虑的主要功能
人造食物的未来到底有多好
人工智能翻译mRASP:可翻译32种语言
input子系统介绍和架构
骁龙810麻烦不断:这7位可取而代之
3D打印提升航空制造效率 霍尼韦尔缩短交付时间
怎么吧手机投屏到电视上
一份超好用的物联网WiFi模块使用指南
魅族魅蓝X评测:双面玻璃设计+Helio P20 配置性能大解析
达内科技助力高校共建人工智能学院
爱立信为环境保护贡献自己的力量
关于QSFP28封装的优点和产品
8K超高清视频有望成为5G时代第一个实现万亿级规模的市场?
导远与中国移动宣布在智慧交通、高精度定位领域建立合作伙伴关系
开辟智能门禁解决方案的新领域
全球云计算一日千里,华为和阿里继续夜郎自大?
黑客探秘
未来中国医疗健康产业的市场发展趋势