上一篇博文介绍了一下USB的枚举过程,主要也是以USB的HID鼠标的枚举过程为例子。本篇博文,我们来详细看一下HID类。

因为主要是摘抄网上资料与USB官方的技术文档,所以将文章类型设为转载。

一、HID类简介

 

    HID是Human Interface Device(人机接口设备)的缩写,它是属于众多USB协议支持类中比较常用的一种。常用的使用HID类的设备有

 

    •Keyboard and pointing device----例如:标准鼠标,跟踪球,操纵杆。
    •Front-panel controls----例如:球柄,开头,滑轮。
    •在电话、 VCR 远程控制、游戏及模拟设备中有可能用到的设备----例如:数据采集器,节流阀,方向盘,方向踏板。
    •也许不需要人为参与,但数据格式与 HID 类设备相同----例如:数据采集枪、温度计、电压表。

 

二、HID类的描述符简介

    

    USB是以描述符的形式组织数据的,USB设备的所有配置都通过描述符实现。

hid模块python HID模块是什么意思_usb

 

    为了更好的理解HID类我们以下图来了解USB的层次关系。

 

hid模块python HID模块是什么意思_描述符_02

    总结: 一个设备只有一个设备描述符, 而一个设备描述符可以包 含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点, 就有几个端点描述符。
    那么作为HID类设备,它特有的描述符是HID Descriptor、Report Descriptor和 Physical Descriptor。HID设备使用这些描述符的组织形式,通过下图体现

hid模块python HID模块是什么意思_数据_03

 

 
    设备成功获取了这些描述符,基本上就识别了这个设备。
    关于USB通用的标准描述符,我们不做过多介绍,这里仅通过贴图的形式,进行简单介绍
1、USB设备描述符

 

 

hid模块python HID模块是什么意思_hid模块python_04

hid模块python HID模块是什么意思_stm32_05

 

 
2、配置描述符

 

 

 

hid模块python HID模块是什么意思_stm32_06

hid模块python HID模块是什么意思_hid模块python_07

hid模块python HID模块是什么意思_数据_08

 

 

3、接口描述符

 

 

hid模块python HID模块是什么意思_stm32_09

hid模块python HID模块是什么意思_描述符_10

 

4、端点描述符

 

hid模块python HID模块是什么意思_stm32_11

 

hid模块python HID模块是什么意思_usb_12

hid模块python HID模块是什么意思_数据_13

 

5、字符串描述符

 

 

hid模块python HID模块是什么意思_数据_14

6、USB协议中关于HID类设备的说明

 

    在STM32提供的USB固件库中(应该也是USB协议的规定),设备描述符在单独的一个数组里。配置描述符、接口描述符、HID描述符、端点描述符在一个数组里,字符串描述符在一个数组里。实际上我们开发HID设备,需要对以上的几个描述符做相应的配置。
    在HID协议中有关于对HID类类型设置的问题,它不是在设备描述符中定义的,而是在接口描述符中定义的,即并不是由设备描述符中的bDeviceClass和bDeviceSubClass来识别一个设备是否为HID设备,而是由接口描述符中的bInterfaceClass和bInterfaceSubClass来确定,且一个HID类设备一般只有一个配置。
    USB规定,对于HID设备,设备描述符中的bDeviceClass、bDeviceSubClass及bDeviceProtocol字段必须为0;USB 协议中,接口描述符 bInterfaceClass 值为 3 时表示 HID 设备。;bInterfaceSubClass字段主要是针对鼠标和键盘来定义的,表示该设备是否是一个启动设备,一般对PC机而言才有意义,意思是BIOS启动时能识别并使用该HID设备,可以取0或1;bInterfaceProtocol字段只有在bInterfaceSubClass字段为1时才有意义,因为真正对HID设备的数据流格式进行描述的是报告描述符,所以该字段的取值实际意义不大,可以取0、1、2。

 

 

hid模块python HID模块是什么意思_stm32_15

    HID 类设备与驱动程序通信使用两种管道 :控制管道或者中断管道
Control Pipe 用于:
    •接收并反馈 USB 控制端的请求。
    •当被 HID 请求时(发送 Get_Report),传送数据。
    •接收主机发送的数据
Interrupt Pipe 用于:
    •接收来自设备的同步数据
    •传送延迟小的数据
    Interrupt Pipe 是可选的,举例来说,如果一个设备 declare 了一个 Interrupt Out endpoint,主机就可以从此端点发送 output report。如果没有 declare 这样的端点,主机可以从 Control Pipe 发送 output report,使用的命令为 Set_Report(output)。
    那么一个典型的配置是

 

 

hid模块python HID模块是什么意思_usb_16

7、HID描述符

 

 

hid模块python HID模块是什么意思_usb_17

    bLength字段指定该HID描述符的长度。
    bDescriptorType字段的取值如下,

 

 

hid模块python HID模块是什么意思_描述符_18

    bcdHID字段指定该HID设备符合的协议版本号。
    bCountryCode字段一般为0。
    bNumDescriptors字段指定类描述符个数,至少为1,即一个ReportDescriptor。
    wDescriptorLenth字段指定上述ReportDescriptor的长度。
    如果给定一个[bDescriptorType]值,则必须指定一个相应的[wDescriptorLength]值。
    同接口描述符和端点描述符一样,当主机请求HID类设备的配置描述符时,HID描述符被一起返回。


8、报告描述符
    报告描述符比较复杂也比较难理解,其语法格式不同于USB标准描述符,它是以项目(item)的方式排列而成,即报告描述符由一个一个的项目组成,数据内容和长度均不固定,根据实际应用需求而定义。

 

hid模块python HID模块是什么意思_数据_19

 

 

    HID的报告描述符已经不是简单的描述某个值对应的某个固定意义了,它已经能够组合出很多种情况,并且需要PC机上的HID驱动程序提供的解释器(parser)来对描述的设备情形进行重新解释,进而组合生成出该HID硬件设备独特的数据流格式,用户可以根据报告描述符的语法规则,自己定义HID设备的数据格式以及各数据位的意义,因此有人称之为“报告描述符脚本语言”。
HID驱动程序包含一个解释器专门用来解析报告描述符,从解释器的角度来看,一个HID类设备可以用下图来表示,等了解了整个报告描述符结构后再回头来看这个图。

 

hid模块python HID模块是什么意思_stm32_20

 

    当一个 Main Item 识别到时, 一个新 “报告”单位将被建立, 并用刚才已收集到的 Item状态(包括 Local Item 和 Global Item)修饰 Main Item。完成后,将所有的 Local Item 清除掉, Global Item 仍然存在,并作为下一个 Main Item 的默认参数值。一个设备拥有多种相似的控制,应该在 Main Item 之前只定义一次 Global Item如前所述,报告描述符是由一个个项目组成的,HID类定义了两种基本的项目格式:长项目和短项目,长项目保留用于以后的应用,所以在此只列出短项目格式。短项目的长度为1-5个字节,其中,第一个字节为标识符,用于标识项目的类型、数据长度等,后面的4个字节为可选的数据,一般无数据或只包含一个字节的数据。

 

hid模块python HID模块是什么意思_stm32_21

 

    HID类协议定义了三种类型的项目:Main、Global、Local,其中,Global和Local只是对Main起描述作用,并不会产生实际的数据传输,有点像C语言中的全局变量和局部变量,只是个人理解,并不准确,下面一一介绍。
    Main项目包含五种子项,由上述bTag字段的值确定,分别为:Input、Output、Feature、Collection、End Collection。
    Input :从设备读取数据到主机,数据可以是表示一个轴或一组杠杆位置的 Variable数据,表示一个或者多个开关、按键的 Array 数据。
    Output :从主机传送数据到设备,数据可以是设置一个轴或一组杠杆位置的 variable数据,用做 LED 控制的 Array 数据。
    Feature :表示并不想传达给终端用户的输入、输出数据。如软件属性,控制面板拨动。
    Collection :表示 Input 、 Output、 Feature item 的集合。如鼠标、键盘、操纵杆、指针。
    End Collection :集合的结束

 

hid模块python HID模块是什么意思_描述符_22

hid模块python HID模块是什么意思_数据_23

 

    Global项目的各子项也由上述bTag字段的值确定,Global项目用来对Main项目进行描述,可以改变Main项目的属性,且对所有后续的项目起作用,除非被另一个Global项目覆盖。

 

 

hid模块python HID模块是什么意思_描述符_24

hid模块python HID模块是什么意思_stm32_25

 

    Local项目与Global项目类似,用来对Main项目进行描述,但是只对其后的第一个Main项目起作用。

 

hid模块python HID模块是什么意思_stm32_26

 

    Usage 是 Report descriptor 的一部分,它描述一个 control 是量测什么的。另外, Usage标签将能够说明下面的操作将会应用到哪些范围(译者注: Usage(Usage_ID)命令)。一个 Report Descriptor 可以有很多 Usage 标签,且 control 和 usage 相对应。一个 array指示 Report Descriptor 的每一个部分代表许多物理控制。每一个控制都有与 Usage 相对应属性。Usage(Usage_Page : Usage_ID)会被解释成 32bit 的无符号数值,高 16bit 作为 Usage Page,低 16bit 作为 Usage_ID。 Usage ID 用于选择 Usage Page 里的使用项目。
    许多设备的 report 是一个每一个部分都有相关定义的结构,但是也有一些设备多种report 结构在同一个端点传输,每一个 report 只有一部分的数据。例如:带有 pointing 结构的键盘,有可能会单独报告“ key press”和“ pointing”数据。这样一来,就需要 Report ID作为 report 的标志了。Report ID 是加在每一个 report 的前缀,如果一个 report 前面没有 ReportID,可以说明只有一种报告结构存在
    Report Descriptor 对设备数据进行了描述。每一个 Main Item 都反映了将要传输的数据大小、传输的数据是否为 absolute 或 relative 以及其它相关资料, 而前面的 Local、Global Item定义了最大、最小数据值等等。 Report Descriptor 包含了一整套的 Item。通过查看 Report Descriptor,应用程序就知道怎样处理传输过来的数据,数据将用于何处。

 

    Main Item 定义了数据块,前面的 Global、 Local Item 作进一步的修饰。 Local Item 只修饰紧跟着的 Main Item, Global Item 将变成缺省的数据性质。看一下下面的例子:

    报告有三个bit,数量为两个,作为输入,报告有8bit,数量为2个(默认使用上一个数量2,因为报告数量的为全局变量) ,作为输入,报告有8bit,数量为2个(受全局变量影响使用之前的配置,所以也是8bit,2个)作为输出。最终我们得到了下图的数据结构

hid模块python HID模块是什么意思_stm32_27

 

    下面我们来看两个实例。(摘自圈圈教你玩USB)

 

    USB鼠标报告符

hid模块python HID模块是什么意思_usb_28

hid模块python HID模块是什么意思_stm32_29

hid模块python HID模块是什么意思_stm32_30

    USB键盘报告符

hid模块python HID模块是什么意思_hid模块python_31

hid模块python HID模块是什么意思_stm32_32

hid模块python HID模块是什么意思_stm32_33

hid模块python HID模块是什么意思_hid模块python_34

hid模块python HID模块是什么意思_描述符_35

9、物理描述符

    物理描述符用于表示身体的那些特定部分可以影响设备的控制特性,该描述符是可选的,HID设备可以根据其本体的设备特性选择是否包含物理描述符,对于大部分设备,物理描述符增加了设备复杂性且并没有多少作用,然而,对于某些设备,特别是具有大量相同的控制(比如按键)能起到很好的作用。
 

 

文中大量摘抄了网络上资料,主要有

1、《圈圈教你玩USB》(极力推荐,非常好,推荐大家都买来看看)

2、http://www.openedv.com/forum.php?mod=viewthread&tid=65837&highlight=USB           (zzu65大神分享的自己整理的资料)

3、USB2.0协议

4、HID1.1协议

5、HID Usage Tables