USB设备中有一大类就是HID设备,即Human Interface Devices,人机接口设备。这类设备包括鼠标、键盘等,主要用于人与计算机进行交互。它是USB协议最早支持的一种设备类。HID设备可以作为低速、 全速、高速设备用。由于HID设备要求用户输入能得到及时响应,故其传输方式通常采用中断方式。
在USB协议中,HID设备的定义放置在接口描述符中,USB的设备描述符和配置描述符中不包含HID设备的信息。因此,对于某些特定的HID设备,可以定义多个接口,只有其中一个接口为HID设备类即可。
1.1HID设备的特点
HID 设备除了传送数据给主机外,它也会从主机接收数据。只要能够符合HlD 类别规范的设备都可以是HID 设备。
设备除了HlD 接口之外,它可能同时还包含有其他的USB 接口。例如影像显示设备可能使用HID 接口来做亮度、对比度的软件控制,而使用传统的影像接口来传送要显示的数据。 USB 扩音器可以使用实时传输来播放语音,同时使用HID 接口来控制音量、 低音等。
HID 类别设备的规范文件主要是以下两份:
Device Class Definition for Human interface Devices
HID Usage Tables
其中前者是 HID 的基本规范文件,后者可以是前者的附件,为开发人员提供实际的控制类型的描述。文件是用来定义让主机了解以及使用 HID 数据的数值。这两份文件是由USB Device Working Group 制定的,可以在下面官方网址下载:
https://www.usb.org/documents?search=&items_per_page=50&page=2
https://www.usb.org/hid
1.2.HID 设备的硬件要求
HID 接口必须符合 Device Class Definition for Human interface Devices 规范内所定义的 HID 类别的需求。在此文件内描述了所需的描述符、传输的频率以及传输的类型等。为了符合规范, HID 接口的端点与描述符都必须符合数个要求。所有的 HID 传输都是使用默认控制管道或是一个中断管道, HID 设备必须有一个中断输入端点来传送数据到主机,中断输出端点则不是必需的。
Control管道用于:
主机与设备之间所交换的数据,可以分成两种类型:
中断管道是控制管道之外的另一种数据交换的方式,特别适合使用在接收端需要定时或是尽可能及时收到数据的时候。中断输入管道携带数据到主机,中断输出管道则是携带数据到设备。在总线忙的时候,控制管道可能会被延迟,而中断管道保证会有可得到的带宽。 HID 不需要一定有中断输出管道。如果没有中断输出管道,主机会在控制管道上使用HID 设备特有的 Set_Report 请求来传送所有的报表。
1.3 HID的固件要求
主机的驱动程序要与 HID 设备通信,设备的固件必须符合下列需求:
如果要传送数据,固件必须支持 Get_Report 控制传输与中断输入传输。如果要接收数据,固件必须支持 Set_Report 控制传输与选择性的中断输出传输。
所有的 HID 数据都必须使用定义过的报表格式来定义报表中数据的大小与内容。设备可以支持一个或多个报表。在固件中的一个报表描述符用来描述此报表,以及如何使用报表数据的信息。
在每一个报表中的一个数值,定义此报表是一个输入(Input )、输出(Output )或是特征(Feature )报表。主机在输入报表中接收数据,在输出报表中传送数据,特征报表可以在任何方向传递。
2.1 HID设备的描述符
HID 设备除了支持 USB 设备的 5 种标准描述符之外,还支持 HID 设备特有的 3 种描述符。
这些描述符是:USB 标准描述符:设备、配置、接口、端点和字符串描述符。
HID 特有的描述符: HID 、报表(Report )和实体(Physical )描述符。
从描述符的关联关系看, HID 描述符是关联于接口 。 所以如果一个 HID 设备有 2 个端点,设备不需要每个端点有一个 HID 描述符。
报告描述符描述设备生成的每条数据以及数据实际测量的数据。
例如,报表描述符(Report descriptor)定义描述位置或按钮状态的项。 物品信息用于:
通过检查项目(统称为报告描述符),HID类驱动程序能够确定来自HID类设备的数据报告的大小和组成。
物理描述符(Physical descriptor)集是可选描述符,其提供关于用于激活设备上的控件的人体的一部分或多个部分的信息。
从前面的 USB 描述符可以看出一个规律,描述符的第一、二字节分别是描述符的长度和类型,描述符的类型字段( bDescriptorType )表明描述符的种类,下表列出了不同描述符的类型字段数值。
对于一个 HID 设备, 设备描述符与配置描述符没有 HID 特定的信息。 其设备描述符的bDeviceClass 和 bDeviceSubClass 字段的值为 0,接口描述符的 bInterfaceClass 字段值为 03,表示设备的该接口是 HID 类别。在接口描述符中其他包含 HID 特定信息的字段还有子类别码( blnterfaceSubClass )与协议码( blnterfaceProtocol 字段) 。
在接口描述符中子类别码字段等于 1 表示此设备支持启动接口( Boot Interface )。如果设备有启动接口,即便主机的 HID 没有加载驱动程序,设备也可以使用。这种情形可能发生在计算机是由 DOS 直接启动,在启动时观看系统设置画面或使用 Wndows 的安全模式时。
含有启动接口的键盘或鼠标可以使用 BIOS 或许多主机支持的默认简单协议。 HID 规范定义了键盘与鼠标的启动接口协议。
如果设备没有启动接口, 并且接口描述符中协议码字段是 1, 表示设备支持键盘接口,协议码字段是 2,表示支持鼠标接口。接口描述符中协议码字段是 0,表示设备不支持启动协议。
在 HID Usage Tables 规范中定义了键盘与鼠标的启动描述符( Boot Descriptor )。BIOS 不需要从设备中读取描述符,因为它知道启动协议,并且假设设备支持启动协议。所以要启动的设备不需要在固件内包含启动接口描述符,它只要在主机尚未要求在报表描述符中的定义协议时支持启动协议即可。在操作系统加载 HlD 驱动程序后会使用Set_Protocol 请求,将设备由启动协议转换成报表协议。
2.2 HID描述符
HID 描述符的主要作用是用来识别 HID 通信所使用的额外描述符。 下表是 HID 描述符结构。
偏移量 | 字段 | 字节数 | 数值类型 | 说明 |
0 | bLength | 1 | Numeric | 描述符字节数 |
1 | bDescriptorType | 1 | Constant | 0x21 = HID 描述符 |
2 | bcdHID | 2 | Numeric | HID 规范版本号( BCD ) |
4 | bCountryCode | 1 | Numeric | 硬件设备所在国家的国家代码 |
5 | bNumDescriptors | 1 | Numeric | 类别描述符数目(至少有一个报表描述符) |
6 | bDescriptorType | 1 | Constant | 类别描述符的类型 |
7 | wDescriptorLength | 2 | Numeric | 报表描述符的总长度 |
9 | [bDescriptorType]... | 1 | Constant | 附加的描述符的类型,可选的 |
10 | [wDescriptorLength]... | 2 | Numeric | 附加的描述符的总长度,可选的 |
HID支持3种描述符。
HID描述符,Report描述符和Physical描述符。
HID设备的这三种描述符时基于类的描述符,他们的值分别如下: