USB-HID类设备
HID(Human Interface Device,人机接口设备)类设备包含键盘、鼠标、触摸板、游戏杆等非常多类别的设备,是直接与人交互的USB设备。
一般的操作系统,都对HID设备有一定支持,符合HID规范的设备都可以免驱运行。
一,HID设备的特点
- 类描述符为HID描述符
- 使用报告(Report)进行数据传输
- 报告使用报告描述符进行规范定义
- 免驱动,操作系统原生支持
通过接口描述符定义设备类型为HID类,类描述符返回HID描述符。
在设置配置之后,主机会向设备发送HID类请求,请求HID描述符中说明的报告描述符。
HID类别设备的规范文件有:
- Device Class Definition for Human interface Devices
- HID Usage Tables
其中前者是HID的基本规范文件,后者提供实际的控制类型的描述。
二,HID描述符
当接口描述符中的bInterfaceClass为0x03,表示这是一个HID设备。
在HID1.1中,此时,bInterfaceSubClass的值为1,表示可以在BOIS阶段使用,为0表示必须在操作系统启动后使用。bInterfaceProtocol为1表示键盘,为2表示鼠标,0为NONE。
HID描述符跟在HID接口描述符后返回,是一种类描述符。
HID描述符结构
| 偏移量/字节 | 域 | 大小/字节 | 说明 |
|---|---|---|---|
| 0 | bLength | 1 | 该描述符的长度 |
| 1 | bDescriptorType | 1 | 描述符类型(HID 描述符为 0x21) |
| 2 | bcdHID | 2 | HID 协议的版本 |
| 4 | bCountryCode | 1 | 国家代码 |
| 5 | bNumDescriptors | 1 | 下级描述符的数量 |
| 6 | bDescriptorType | 1 | 下级描述符的类型 |
| 7 | wDescriptorLength | 2 | 下级描述符的长度 |
| 9 | bDescriptorType | 1 | 下级描述符的类型(可选) |
| 10 | wDescriptorLength | 2 | 下级描述符的长度(可选) |
| … | … | … | …(可选) |
bLength——描述符长度bDescriptorType——描述符编号,HID为0x21bcdHID——HID版本,对HID1.1是0x0110bCountryCode——国家代码,对美式键盘,为33即0x21bNumDescriptors——下级描述符数量bDescriptorType——下级描述符类型,报告描述符为0x22bDescriptorLength——下级描述符长度
如果有多个下级描述符,bDescriptorType和bDescriptorLength将交替重复。
下级描述符分类
常见的下级描述符有两类:
| 描述符类型值 | 名称(英文) | 说明与用途 |
|---|---|---|
| 0x22 | Report Descriptor(报告描述符) | 必选。定义 HID 设备上报给主机的数据结构(按键位图、轴坐标、LED 状态等)。每个 HID 接口必须包含至少一个报告描述符。 |
| 0x23 | Physical Descriptor(物理描述符) | 可选。用于描述设备上物理控制部件(按键、旋钮、滚轮等)的位置、形状、功能等信息。绝大多数 USB HID 设备并不实现物理描述符。 |
一般来说,只会出现一个报告描述符。
三,HID请求
USB请求中bmRequestType中设置该请求为类请求,bRequest标志HID请求种类。如下表:
| bRequest 值 | 名称 | 数据方向 | 功能说明 |
|---|---|---|---|
| 0x01 | GET_REPORT | 设备→主机 | 让设备返回一份 输入/输出/特性报告(Input/Output/Feature Report)。常用于启动阶段拉取当前按键状态或传感器值。 |
| 0x09 | SET_REPORT | 主机→设备 | 主机向设备下发一份 输出/特性报告,典型场景:初始化时点亮键盘 LED、设置触控板参数。 |
| 0x02 | GET_IDLE | 设备→主机 | 查询 HID 设备当前的 idle 时间(指当HID设备没有数据报告时,主机限制中断输入端点的报告间隔时间。默认情况下,空闲速率为0。GetIdle是一个非必要请求。单位:4ms)。 |
| 0x0A | SET_IDLE | 主机→设备 | 设置上述空闲率。Windows常设置为0. |
| 0x03 | GET_PROTOCOL | 设备→主机 | 仅对 Boot Device(键盘/鼠标)有效:读取当前协议模式——0 = Boot Protocol,1 = Report Protocol。 |
| 0x0B | SET_PROTOCOL | 主机→设备 | 仅对 Boot Device 有效:切换协议模式。BIOS/UEFI 阶段使用 Boot Protocol;操作系统加载后切到 Report Protocol。 |
设置IDLE时间将让设备在无变化时,在一定时间不对中断传输响应。
四,报告描述符
设置完配置后,主机根据HID描述符向接口发送标准获取描述符请求,请求报告描述符,wIndex包含接口号。
如果没有输入输出端口,主机也可以通过端点0,利用HID请求返回报告。
具体报告描述符的语法这里不展开(因为太多太杂了),这里只需要明确一个概念:报告描述符描述了HID设备传输的数据的功能和意义。
五,数据的传输
HID设备使用报告传输数据,数据的格式定义由报告描述符确定,使用中断传输,主机保证在某时间内进行一次查询。
报告分为输入和输出报告,分别由IN和OUT端点完成,使用什么报告由报告描述符决定。
以键盘为例,要实现键盘的功能需要同时使用IN和OUT,用于主机向键盘发送信号灯状态(大写锁定等),键盘向主机发送按键状态。完成枚举后,主机每隔一段时间会发送IN、OUT令牌包来启动中断传输过程。在IN传输中,设备按照报告描述符的设定,准备好按键状态组合成几个字节的数据,然后发送给主机;在OUT传输中,设备接收来自主机的数据,并按照报告描述符的设定进行解释,提取对应状态灯的状态。
六,自定义HID
除了常见的鼠标键盘等HID设备可以直接作为操作系统的外设输入,还有一类HID设备不是任何外设,其功能由用户自定义,用户只能通过调用系统API与其进行数据交互。
定义CustomHID在报告描述符中定义HID类别为0x21即可,具体实现过程在下一篇文章中进行讲解。

浙公网安备 33010602011771号