UEFI开发探索84- YIE002USB开发板(07 制作HID设备)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

在之前的博客中,曾经谈到制作USB HID需要掌握的背景知识。包括USB软件架构、USB描述符和USB命令。前两个已经讨论过了,本篇介绍USB命令。

1 USB命令(USB Device Request)

USB规范定义了设备请求(USB Device Request),以更好地完成USB主机对总线上所有USB设备的统一控制。此设备请求由USB主机发往USB设备,为方便理解USB主机和设备间的主从关系,后续行文中一律称为“USB命令”。

USB命令包括USB标准命令、类命令和厂商命令。这些命令的格式都是相同的,如表1所示。

表1 USB命令的结构

偏移字段 长度数值描述
0  bmRequesType1位图D7:数据的传输方向
  0=主机->设备
  1=设备->主机
D6…5:命令的类型
 0=标准命令 1=类命令
 2=厂商命令 3=保留
D4…0:接收对象
 0=设备 1=接口 2=端点
 3=其他  4…31=保留
1  bRequest1命令的序号
2  wValue2根据不同的命令,含义也不同
4  wIndex2索引或偏移根据不同的命令,含义不同,主要用于传送索引或者偏移
6  wLength2如果有数据阶段,此字段为数据的字节数

标准命令是每种USB设备都要支持的,类命令则与USB设备所述类有关,比如USB HID设备有HID类特有的命令,如Get_Report、SetReport等。

2 USB标准命令

USB 1.1的规范中,规定了11种USB标准命令,用来完成各种目的。根据不同的命令,相应的字段含义也有所不同。表2列出了11个USB标准命令的功能。

表2 USB标准命令

命令请求号功能描述
Get_Status0x00读取USB设备、接口或者端口的状态
Clear_Feature0x01清除或禁止USB设备、接口或端点的某些特征
Set_Feature0x03设置或使能USB设备、接口或端点的某些特征
Set_Address0x05分配USB设备地址
Get_Descriptor0x06读取描述符
Set_Descriptor0x07更新已有的描述符或添加新的描述符
Get_Configuration0x08读取USB设备的当前配置值
Set_Configuration0x09为USB设备选择一个合适的配置值
Get_Interface0x0A获得设备接口当前工作的选择设置值
Set_Interface0x0B激活USB设备的某个接口
Synch_Frame0x0C设置并报告端点的同步帧号

在USB规范中,对于这些标准的USB命令,所有的USB设备必须都支持,并能够对命令进行响应。如果不需要对命令进行操作,也必须准备一个空的响应。除了这些标准的USB命令,对于不同的类,也有类相关的USB命令。比如人机接口类设备有Set_Report、Get_Report等命令,集线器类设备有GetHubStatus、GetBusState等命令。在开发相应类设备的时候,也需要熟悉这些类本身特有的USB命令。

我所准备的嵌入式示例程序中,主要需要了解的USB标准命令是Get_Descriptor,其余的命令基本是由框架代码生成的,了解有这些处理过程就可以了。下面详细介绍Get_Descriptro命令,其余的命令可以参考USB规范中的描述。

如表3所示,给出了Get_Descriptor命令的结构。

表3 Get_Descriptor命令的结构

偏移字段内容
0bmRequesType值为10000000B,设备到主机
1bRequestGET_DESCRIPTOR,0x06
2wValue描述符的类型和描述符的索引值
4wIndex0或语言标识(LANGID)
6wLength描述符的长度

Get_Descriptor命令用来获取USB设备的各种描述符,包括设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符。需要获取的描述符类型,由wValue字段给出。wValue由两个字节组成,高字节表示描述符的类型,低字节表示描述符的索引值。

wIndex字段除去获取字符串描述符之外,其他情况下设置为0。获得字符串描述符的过程分为两步:第一次发送命令后获得语言标识;第二次发送命令时,将语言标识赋给wIndex字段,需要获取的字符串描述符的索引值赋给wValue字段,即可获得所需要的字符串。

Get_Descriptor命令中的字段wLength,表示描述符的字节长度,由USB主机指定。当指定wLength比实际的描述符长度小时,USB设备严格按照主机指定的字节长度返回描述符信息;当wLength比实际的描述符长度大时,USB设备值返回描述符长度的信息。比如在访问配置描述符时,USB主机不清楚配置信息的总长,可以将Get_Descriptor命令中的wLength设置为4,得到配置描述符中wTotalLength。然后,重新发送Get_Descriptor命令,此时将wLength设置为wTotalLength的值,从而获得整个配置描述符信息。

3 USB HID的类命令

HID设备除了支持标准的USB命令外,还支持6个HID特定的类命令,如表4所示。

表4 HID的类命令

命令请求号功能描述
Get_Report0x01USB主机接收HID设备发来的报告
Get_Idle0x02用于读取HID设备当前空闲速率
Get_Protocol0x03用于读取HID设备的协议值
Set_Report0x09USB主机向HID设备发送报告
Set_Idle0x0A用于设置HID设备的空闲速率
Set_Protocol0x0B用于设置HID设备的协议值

HID的类命令,其数据结构与USB的标准命令类似,而且也是采用控制传输发送的。本章准备的HID示例中,主要用到了Get_Report和Set_Report两个命令,下面介绍这两个命令。

Get_Report命令用于获取HID设备发送来的报告,它主要在HID设备初始化和读取HID报告时使用。此命令是所有HID设备都必须支持的,其结构如表5所示。

表5 Get_Report命令的结构

偏移字段内容
0bmRequesType值为10100001B,设备到主机
1bRequestGET_REPORT,0x01
2wValue报告类型及报告ID
4wIndex用于指明支持此命令的接口号码
6wLength报告长度

其中,wValue用来指明报告的类型。它由两个字节组成,低字节表示报告ID。高字节值为1时,表示Input报告;值为2时,表示Output报告;值为3时,表示Feature报告。

Set_Report命令用于USB主机向HID设备发送报告数据,它与Get_Report命令类似,只是数据传输的方向不同。Set_Report命令并不是所有HID设备都必须支持的,其结构如表6所示。

表6 Set_Report命令的结构

偏移字段内容
0bmRequesType值为00100001B,主机到设备
1bRequestSET_REPORT,0x09
2wValue报告类型及报告ID
4wIndex用于指明支持此命令的接口号码
6wLength报告长度

从UEFI开发探索81到本篇,所有关于制作USB HID设备的背景知识,就全部介绍完了。熟练掌握这些知识后,可以在任何一款带USB功能的单片机上,实现我们所需要的HID设备。

下篇将以YIE002-STM32型开发板为例(也即主芯片为STM32F103C8T6的YIE002开发板),实现一个具三种通信方式的USB HID设备。

943 total views, 3 views today

发表评论

电子邮件地址不会被公开。