USB HIDUSB Human Interface Device Class)是 USB 设备类规范中承载 HID 的方式,用标准 USB 描述符、HID 类描述符、HID Report Descriptor 和 interrupt/control 传输让主机免厂商驱动接入人机接口设备。

它常用于键盘、鼠标、触控板、手柄、扫描枪、遥控器和少量厂商自定义控制器。USB HID 的关键优势是主流操作系统都有通用 HID 类驱动。

核心问题

USB 只提供设备枚举、配置、接口、端点和传输机制。主机还需要知道一个接口属于哪类设备,以及接口传输的数据怎么解释。

USB HID 解决的是“在 USB 上如何标准化发现、描述和交换 HID report”的问题。它让设备在插入时通过标准描述符告诉主机:我是 HID 接口,我的 report descriptor 在哪里,我会通过哪些端点收发 report。

核心对象

对象含义工程关注点
USB device物理 USB 外设VID/PID、电源、速度、复合设备结构
Configuration descriptor描述设备当前配置一个设备可有多个 interface
Interface descriptor声明某个接口的 class/subclass/protocolHID class、Boot Keyboard、Boot Mouse
HID descriptorHID 类专用描述符指向 report descriptor,声明 HID 版本
HID Report Descriptor描述 report 布局和语义主机解析 input/output/feature report 的依据
Interrupt IN endpoint设备向主机上报 input report轮询间隔、最大包长、延迟
Interrupt OUT endpoint主机向设备发送 output report,可选LED、震动、控制命令
Control endpoint 0枚举和类请求通道GET_DESCRIPTOR、GET_REPORT、SET_REPORT

USB HID 的“免驱”来自这些描述符和类请求共同形成的标准契约,而不是主机猜测设备行为。

核心机制

1. 枚举阶段发现 HID 接口

USB HID 插入后的典型枚举路径是:

host reads device descriptor
  -> host reads configuration descriptor
  -> host finds HID interface
  -> host reads HID descriptor
  -> host reads report descriptor
  -> host binds HID class driver

Interface descriptor 中的 class/subclass/protocol 决定主机是否按 HID 类处理该接口。键盘、鼠标可以使用 Boot Interface Subclass,让早期启动环境用简化协议识别它们。

2. 运行时通过 report 交换数据

USB HID 常用 interrupt IN 端点上报输入:

device firmware
  -> builds input report
  -> host polls interrupt IN endpoint
  -> device returns report
  -> OS HID driver parses report

“interrupt endpoint”名字容易误导。USB 里它不是设备主动打断主机,而是主机按端点声明的轮询间隔定期发起事务。设备有数据时在轮询中返回 report。

主机给设备的 output report 可以走 interrupt OUT 端点,也可以走 control endpoint 的 SET_REPORT 类请求。Feature report 常用于配置或状态查询,可能通过 control transfer 读写。

3. report descriptor 决定字节布局

设备固件发出的每个 report 必须和 report descriptor 一致。可以用一个简化关系表示:

runtime_report_bytes must match report_descriptor_layout

这里的 report_descriptor_layout 包括 Report ID、字段顺序、字段 bit 长度、usage、logical range 和 padding。如果 descriptor 声明 4 字节 input report,但固件发送 5 字节或字段顺序不同,主机就会错解数据。

工程用途

  • 标准键鼠和输入设备:插上即可被操作系统识别。
  • 扫描枪和按键板:常模拟键盘,把扫描结果或按钮事件变成按键输入。
  • 工业控制面板:少量按键、旋钮、指示灯可以用 HID report 表达。
  • 自定义免驱通信:使用 Vendor-defined Usage Page 收发低速配置、状态或测试命令。
  • 嵌入式 USB device:MCU 或 SoC 通过 USB device controller 暴露 HID 接口给 PC。

调试 USB HID 时,常看 USB 枚举日志、lsusb -v、report descriptor 解析结果、端点最大包长、轮询间隔、hidraw 节点、系统输入事件和抓包工具输出。

边界与常见坑

  • USB HID 不等于所有 USB 外设:摄像头通常是 UVC,网卡、串口、存储都有自己的设备类。
  • USB HID 不适合高吞吐数据流:HID 偏低速输入/控制;大量图像、音频、日志或固件传输应考虑其他类或自定义协议。
  • Boot Protocol 很窄:它只覆盖简化键盘和鼠标,不能代表完整 HID report descriptor 能力。
  • 复合设备要分清接口:一个 USB 设备可以同时有 HID、CDC、UVC 等多个接口,驱动绑定按 interface 发生。
  • 端点方向不要混淆:IN/OUT 方向以主机视角命名,IN 是设备到主机,OUT 是主机到设备。
  • 自定义 HID 仍需要主机应用协议:通用 HID 驱动负责搬运 report,不负责理解厂商业务命令。
  • 描述符长度和实际返回必须一致:HID descriptor 中报告的 report descriptor length 写错,会导致主机读不全或解析失败。

相关术语

外部参考