我想要使用的外部 USB 键盘被识别为 USB HID 设备,但在 Linux 启动时它不起作用。当插入 Windows 桌面时它可以工作,并且在 grub 中也可以工作,但在系统启动时则不能。
该设备在 USB 端口 (05a4:8003) 上可见:
$ lsusb
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 003 Device 002: ID 046d:c078 Logitech, Inc.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 05a4:8003 Ortek Technology, Inc.
当dmesg
设备连接时没有显示错误:
[ 466.932272] usb 1-1.2: new full-speed USB device number 4 using ehci_hcd
[ 467.026740] usb 1-1.2: New USB device found, idVendor=05a4, idProduct=8003
[ 467.026745] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 467.026756] usb 1-1.2: Product: USB Keypad
[ 467.026758] usb 1-1.2: Manufacturer: Keypad
[ 467.027939] input: Keypad USB Keypad as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/input/input13
[ 467.028099] hid-generic 0003:05A4:8003.0004: input,hidraw1: USB HID v1.10 Keyboard [Keypad USB Keypad ] on usb-0000:00:1a.0-1.2/input0
[ 467.029600] input: Keypad USB Keypad as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.1/input/input14
[ 467.029726] hid-generic 0003:05A4:8003.0005: input,hidraw2: USB HID v1.10 Mouse [Keypad USB Keypad ] on usb-0000:00:1a.0-1.2/input1
输入/事件设备已创建,但未响应。我想知道设备注册两次(键盘输入和鼠标输入)是否有问题。
我正在 Ubuntu 13.04 系统上进行测试。预期的目标系统是带有 Rasbian 的 Raspberry Pi。由于问题以同样的方式出现在 Rasbian 上,我认为它与 Linux 相关。
我怎样才能进一步调试这个?知道什么可能导致这种反应迟钝的行为吗?
答案1
这个USB HID设备在Windows中工作的原因是因为可能有为其编写的特定驱动程序,它在GRUB中工作的原因是该设备在所谓的引导模式。 USB HID 设备支持两种操作模式:引导模式和 HID 模式。前者使得可以在 BIOS 中使用该设备,而无需 BIOS 实现完整的 HID 堆栈。后者提供了更大的灵活性,可以添加扩展功能(如额外的按钮)。对引导模式的支持通过接口描述符中存在引导接口子类标志来指示(请参阅lsusb -v -d 05a4:8003
):
Interface Descriptor:
...
bInterfaceSubClass 1 Boot Interface Subclass
对 Linux 内核源代码 (3.14-rc8) 的快速 grep 没有显示此 USB HID 设备的特殊驱动程序。因此,内核回退到通用 HID 驱动程序 ( hid-generic
)。然而,该设备和 Linux 使用的驱动程序似乎不兼容。
要查看设备是否生成任何(不可见)活动,请安装该evtest
程序并运行sudo evtest
。当提示输入设备时,输入与您的键盘匹配的号码。如果一切正常,那么您应该会看到按键事件。
如果您没有看到任何按键并且想要进一步调试,请安装wireshark
以捕获 USB 接口(使用 usbmon)。正如您在输出中看到的lsusb
,输入设备连接到总线 1,因此您应该指定usbmon1
为接口。捕获USB流量的命令是:
sudo dumpcap -i usbmon1 -w - > usb.pcapng
usb.pcapng
(此方法允许您以普通用户身份进行写入,另一种方法是使/dev/usbmon1
普通用户可读或在创建文件后更改所有权。)
分析 USB HID 捕获
作为非特权用户,您现在可以开始分析捕获的 USB 流量。您需要了解以下基础知识USB和高压气体放电管来理解它。最简单的HID设备通常有两个端点,一个双向控制端点(EP0,这个总是存在的)和一个用于传输数据的中断端点从装置到USB 主机(“计算机”)。
我制作了一个带注释的捕获示例并将其上传到https://www.cloudshark.org/captures/a6c9580208b7。我建议您阅读数据包注释,以更好地了解它是如何工作的。当您在 Wireshark 中离线打开此数据包时,我建议添加一些颜色(查看 -> 着色规则):
frame.comment
- 更容易查看哪些帧收到了命令usb and frame.len == 64
(或其否定,usb and not frame.len == 64
) - 更快地注意到哪些数据包获得了有效负载。
还建议添加一些额外的列(右键单击列,“列首选项”):
usb.urb_type
- 查看数据包是否提交 (URB_SUBMIT
) 到设备 () 或从设备 () 接收URB_COMPLETE
。usb.transfer_type
- 查看您是否正在查看控制数据(通过 EP0)或其他数据(例如 USB HID 设备的中断数据)。usb.endpoint_number.direction
- 查看方向数据传输(IN 是从设备到主机(“PC”),OUT 是从主机(“PC”)到设备)。
我已将这些列拖动到 Len(gth) 列旁边并调整大小,以便信息列在这三个 USB 列的右侧仍然可见。
完成这些设置后,您现在可以开始分析。按任意键都会生成中断,其中的数据符合 HID 描述符的格式。如果没有,则可能需要一些特定于供应商的命令(即特殊驱动程序)或者 Linux USB (HID) 堆栈中存在错误。