Ubuntu 16下STM32自定义HID键盘无法输出字符问题求助
这问题我之前帮朋友排查过类似的,结合Ubuntu 16的HID处理逻辑,给你列几个最可能的原因和对应的排查/解决步骤:
1. 缺少完整的按键事件周期
很多DIY HID键盘容易犯这个错:只发送按键按下的报告,却不发送按键释放的报告。Windows对这种情况容错性很高,会自动处理成持续输入,但Ubuntu 16的Xorg输入栈需要完整的「按下→释放」事件才会正确输出字符——哪怕你是要重复发送'A',也得每次都先发按下报告,延迟一小段时间(比如10ms)再发释放报告,然后再循环。
你可以用evtest再仔细看一下输出:如果一直显示KEY_A (28): pressed,没有对应的released记录,那就是这个问题,补全释放报告即可。
2. 输入焦点未正确激活
Ubuntu的桌面环境(比如Unity)只会把输入设备的事件传递给当前激活的窗口。哪怕evtest能收到数据,如果你的测试窗口(比如文本编辑器)没被选中激活,屏幕上也不会显示字符。
解决方法很简单:打开gedit或者gnome-terminal,点击窗口确保它处于激活状态,再测试你的HID设备。另外可以用xinput list命令查看你的设备是否被识别为「keyboard」类设备,如果被归类为其他输入设备,Xorg可能不会把它的事件映射到文本输入。
3. HID报告描述符不符合标准规范
Windows对HID报告描述符的兼容性很强,哪怕有小偏差也能正常解析,但Ubuntu 16使用的旧版hid-input驱动对规范的要求更严格。比如你的描述符可能在Usage Page、Usage或者报告长度的定义上和标准USB HID键盘有差异。
标准HID键盘的报告描述符核心结构(简化版)如下:
0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x19, 0xE0, // Usage Minimum (224) 0x29, 0xE7, // Usage Maximum (231) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Var,Abs) 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0x81, 0x01, // Input (Cnst,Arr,Abs) 0x95, 0x06, // Report Count (6) 0x75, 0x08, // Report Size (8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x65, // Logical Maximum (101) 0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x19, 0x00, // Usage Minimum (0) 0x29, 0x65, // Usage Maximum (101) 0x81, 0x00, // Input (Data,Arr,Abs) 0xC0, // End Collection
对比一下你STM32里的描述符,确保没有偏离这个结构,比如报告长度必须是8字节(修饰键1字节+保留1字节+6个按键码字节)。
4. 用户缺少输入设备的访问权限
虽然dmesg显示设备被正常识别,但当前用户可能没有访问输入设备节点的权限。Ubuntu的输入设备(/dev/input/event*)默认属于input用户组,如果你的用户不在这个组里,Xorg可能无法读取设备事件。
排查方法:运行ls -l /dev/input/event*,看输出里的组是否为input;然后用groups命令检查当前用户是否在input组中。如果不在,执行以下命令添加权限:
sudo usermod -aG input $USER
添加完成后重新登录系统,再测试设备。
5. Xorg输入驱动的配置问题
Ubuntu 16的Xorg可能没有自动加载合适的输入驱动,或者你的设备被Xorg忽略了。可以查看Xorg的日志文件/var/log/Xorg.0.log,搜索你的设备名称(比如在dmesg里看到的设备名),看有没有类似「ignoring device」「failed to load driver」的错误信息。
如果发现驱动加载问题,可以尝试手动重装xserver-xorg-input-evdev包:
sudo apt-get install --reinstall xserver-xorg-input-evdev
然后重启Xorg或者系统再测试。
内容的提问来源于stack exchange,提问作者Ankit

