【usb】linux内核USB键盘驱动解析--普通键值上报及转化

该文深入解析Linux5.10内核中的USB键盘驱动,重点分析了用于检测按键按下和释放的for循环代码段。通过对kbd->old和kbd->new两个数组的对比,利用memscan函数检查按键状态变化,当按键值在新报文中消失或出现时,触发相应的按键释放或按下事件报告。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概况

  • 建议阅读前置文章【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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr成文

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值