一、概况
- 建议阅读前置文章【usb】linux内核USB键盘驱动解析–特殊键值上报及转化
- 以Linux5.10内核中USB键盘驱动为例进行解析:https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.10.tar.gz
- 文件路径:linux-5.10/drivers/hid/usbhid/usbkbd.c
- 本次我们主要分析第120~139行的这个for循环。
二、探索
- for循环变量i范围是2-7,是因为普通键值存放在数组的第2-7个元素。第一个存放的是特殊键值,第二个保留。
-
kbd->old[i] > 3
这个判断是因为,0-3几个键值是保留的没有对应的物理按键。所以我们不需要关注。具体说明见hut1_4第10节。
if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
if (usb_kbd_keycode[kbd->old[i]])
input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
- 上面这段代码,首先memscan的功能是 在一块内存中查找一个字符,也就是在
kbd->new + 2
这块内存中查找字符kbd->old[i]
。6表示kbd->new + 2
这块内存大小为6。如果找到了则返回该字符地址,否则返回该内存块末尾地址+1。 - 所以这段代码的意思是,在新报上来的键值中查找旧的键值,如果没有找到,并且
if (usb_kbd_keycode[kbd->old[i]])
旧的键值为有效键值,那么就上报旧的键值已释放(按键已松开/抬起)。
if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
if (usb_kbd_keycode[kbd->new[i]])
input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
- 这段代码逻辑和上面的差不多,在旧的键值中查找新的键值,如果没有找到这个新的键值,并且这个新的键值是有效的,那么就上报该新键值被按下。
三、总结
- 在
kbd->old
中保存了上次报上来的键值,kbd->new
中是本次报上来的键值。如果上次报了某键值,但是本次没报,说明该按键被释放了,所以上报案件旧释放事件。如果上次没有报某按键而这次报了,说明该按键是这次被按下了,所以要上报按键按下事件。
四、参考资料
hut1_4
memscan(9) — linux-manual-4.8文章来源地址https://www.toymoban.com/news/detail-404613.html
文章来源:https://www.toymoban.com/news/detail-404613.html
到了这里,关于【usb】linux内核USB键盘驱动解析--普通键值上报及转化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!