第五篇 USB设备枚举过程(4)
上一篇:https://blog.****.net/qq_40088639/article/details/109765847
六、语言ID描述符和字符串描述符的请求
这个阶段,Host会先请求语言ID字符串,然后再依次请求厂商字符串、产品字符串和***字符串。
1. 字符串描述符的结构
主机在获得配置描述符集合之后,会下发获得语言ID的请求,以及获得字符串的请求。在USB协议中,字符串描述符是可选的。在设备描述符中,申请了三个非0的索引值:
1:是厂商字符串的索引值 2:是产品字符串的索引值 3:是产品***的索引值 |
主机通过索引值来获取对应的字符串数据。索引值为0则表示获取的是语言ID字符串。字符串描述符的结构很简单,如下:
语言ID描述符的结构
偏移量/字节 |
域 |
大小/字节 |
说明 |
0 |
bLength |
1 |
该描述符的长度(4字节=0x04) |
1 |
bDescriptorType |
1 |
描述符类型(字符串类型为0x03) |
2 |
wLANGID |
2 |
语言ID号 |
字符串描述符的结构
偏移量/字节 |
域 |
大小/字节 |
说明 |
0 |
bLength |
1 |
该描述符的长度(n) |
1 |
bDescriptorType |
1 |
描述符类型(字符串类型为0x03) |
2 |
bString |
N |
UNICODE编码的字符串 |
说明:
(1) 语言ID,只使用美式英语的一种,即0x0409.
(2) bString字段使用的是UNICODE编码的字符串,使用两个字节来表示一个字符。
2. 字符串描述符在程序中的定义
首先,在定义设备描述符的时候,厂商字符串索引值、产品字符串索引值、产品***索引值都不为0。并且按照协议,分别给设备描述符的iManufacturer、iProduct、iSerialNumber赋了对应的索引值。设备描述符中,对这三个域的赋值如下:
因为,设备描述符之前已经传入主机,主机经过分析得知,设备这边是有定义这些字符串的(索引值不为0,就说明有定义),接下来,主机会单独请求获得这些字符串数据。
实例:Host下发的数据包(标准请求) 请求获得语言ID字符串: bmRequestType=0x80 bRequest=0x06 wValue =0x300 wIndex=0x00
请求获得产品字符串: bmRequestType=0x80 bRequest=0x06 wValue=0x302 wIndex=0x409
请求获得产品***字符串: bmRequestType=0x80 bRequest=0x06 wValue=0x303 wIndex=0x409
根据bRequest可知这是一个获得描述符的请求,对wValue高字节的解析可知,这是一个获得字符串描述符的请求,对wValue低字节的解析可知,这是一个获得XXX字符串的请求。
注意低字节表示字符串索引值。高字节表示描述符类型,都是属于字符串描述符,所以都是03。 |
这些字符串在程序中的定义如下:
其中
CONFIG_USB_DEVICE_MANUFACTURER
CONFIG_USB_DEVICE_PRODUCT
CONFIG_USB_DEVICE_SN
这三个宏被定义在当前工程配置文件prj.conf中,如下:
/******************************************************************************
(1) 配置文件prj.conf里面定义: CONFIG_USB_DEVICE_MANUFACTURER="Actions
所以厂商字符串描述符总字节数:
sizeof("Actions")*2 = 7 * 2 =14 Byte + bLength(1 Byte) + bDescriptorType(1 Byte) = 16 Byte
(2) 配置文件prj.conf里面定义: CONFIG_USB_DEVICE_PRODUCT="USB Dongle"
所以产品字符串描述符总字节数:
sizeof("USB Dongle")*2 = 10 * 2 = 20 Byte + bLength(1 Byte) + bDescriptorType(1 Byte) = 22 Byte
(3) 配置文件prj.conf里面定义: CONFIG_USB_DEVICE_SN="0123456789AB"
所以产品***描述符总字节数:
sizeof("0123456789AB") * 2 = 12 * 2 = 24 Byte + bLength(1 Byte) + bDescriptorType(1 Byte) = 26 Byte
******************************************************************************/
对照协议分析仪进行分析:
串口打印跟踪:
七、又再一次获取设备描述符
协议分析仪:
串口跟踪打印:
八、又再一次获取配置描述符
这次和第一次获取描述符有所不同,第一次获取配置描述符,请求的长度是255(0xFF)字节。我们可以认为这是不合理的,正确的请求应该是:第一次先获取9字节长度的配置描述符,然后根据配置描述符中配置集合的长度,再次获取配置描述符集合。第二次获取的时候,设备会将配置描述符、接口描述符、类特殊描述符、端点描述符等一并返回。这里分两次获取,也就是有两个事务(或者说有两次数据传输)。这一次获取配置描述符,是比较合理的请求。
协议分析仪:
串口跟踪打印:
下一篇: