USB协议详解第8讲(USB描述符-字符串和语言ID描述符)
1.字符串描述符相关概念
字符串描述符:首先,字符串描述符就是用字符串描述一个设备的一些属性,毕竟人能看懂的是字符,而不是十六进制,描述的属性包括设备厂商名字、产品名字、产品序列号、各个配置名字、各个接口名字,还有就是由我们用户自己定义的字符串,说白了就是起名字,让人们一看就知道这个设备是什么设备,字符串描述符对于设备来说是可选的。
语言ID描述符:给大家明确一点,其实语言ID描述符也是字符串描述符,它比较特殊,是用来告诉主机其他字符串描述符里面的字符串都支持哪国家语言,因为USB标准全球都在用,字符串的显示形式也是各种各样。
主机需要先获取语言ID描述符确定都用哪些编码,才能正确解析后续得到的字符串描述符。再次说明,语言ID描述符和字符串描述符是一起出现的,因为只有确定了用什么语言,才能读懂后面的字符串。
2.语言ID描述符组成、详解、代码
(1)语言ID描述符组成
(2)语言ID描述符详解
1.bLength
描述符长度,这里的长度不确定,有可能会指示主机需要支持多国语言;
2.bDescriptorType
描述符类型,语言ID描述符也是字符串述符,类型为0x03;
3.wLANGID[0]
要支持的语言ID号,从USB_LANGIDs.pdf这个文档中查询,我也没有下载,大家可以去搜索查询,这里截取了一张图,其实我们用的最多就是标红的两种编码
4.wLANGID[n]
有可能会支持多种语言,我们这里先只支持一种,支持U.S English。
(3)语言ID描述符STM32代码
/* USB String Descriptors (optional) */
const uint8_t CustomHID_StringLangID[CUSTOMHID_SIZ_STRING_LANGID] =
{
CUSTOMHID_SIZ_STRING_LANGID,
USB_STRING_DESCRIPTOR_TYPE,
0x09,
0x04
}; /* LangID = 0x0409: U.S. English */
3.字符串描述符索引剖析
我们前面学过设备描述符、配置描述符、接口描述符,里面有各种字符串描述符索引项,大家肯定有疑惑不知道里面设置为多少,为什么厂商字符串索引、产品字符串索引、产品序列号字符串描述符索引规定为1、2、3等等。
在这里给大家解释下,其实索引号0是给语言ID字符串描述符的,主机必须先获取语言ID字符串描述符才能知道是哪国语言。所以设备如果要实现字符串描述符主机请求的响应,就必须先实现语言ID字符串描述符,当主机使用GET_DESCRIPTOR请求字符串描述符并且索引值为0时,设备必须返回语言ID字符串描述符(记住这里是必须)。
其它索引号也是主机规定的,主机请求索引号为1的字符串描述符,主机收到设备返回的字符串以后就认为是对厂商的字符串说明,设备你如果返回其它的字符串就是不按套路出牌,主机就会显示错位,比如会把厂商字符串显示到产品显示那块去。
如果设备不支持厂商字符串描述符、产品字符串描述符、产品序列号字符串描述符、配置字符串描述符、接口字符串描述符,则对应地方索引应该被设置为0,如下图几处地方设置为0即可。
4.字符串描述符组成、详解、代码
(1)字符串描述符组成
(2)字符串描述符详解
1.bLength
描述符长度,这里的长度不确定,因为字符串多长不定;
2.bDescriptorType
描述符类型,字符串描述符类型为0x03;
3.bString
UNICODE编码的字符串
(3)字符串描述符STM32代码
ONE_DESCRIPTOR String_Descriptor[4] =
{
// index = 0;
{(uint8_t*)CustomHID_StringLangID, CUSTOMHID_SIZ_STRING_LANGID},
// index = 1;
{(uint8_t*)CustomHID_StringVendor, CUSTOMHID_SIZ_STRING_VENDOR},
// index = 2;
{(uint8_t*)CustomHID_StringProduct, CUSTOMHID_SIZ_STRING_PRODUCT},
// index = 3;
{(uint8_t*)CustomHID_StringSerial, CUSTOMHID_SIZ_STRING_SERIAL}
};
const uint8_t CustomHID_StringVendor[CUSTOMHID_SIZ_STRING_VENDOR] =
{
CUSTOMHID_SIZ_STRING_VENDOR, /* Size of Vendor string */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
// Manufacturer: "STMicroelectronics"
'M', 0, 'y', 0, 'U', 0,'S', 0,'B', 0, '_', 0, 'H', 0,'I',0,'D',0
};
const uint8_t CustomHID_StringProduct[CUSTOMHID_SIZ_STRING_PRODUCT] =
{
CUSTOMHID_SIZ_STRING_PRODUCT, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'B', 0, 'y', 0, ' ', 0, 'v', 0, 'i', 0, 'e', 0,'w',0,'t',0,'o',0,'o',0,'l',0
};
uint8_t CustomHID_StringSerial[CUSTOMHID_SIZ_STRING_SERIAL] =
{
CUSTOMHID_SIZ_STRING_SERIAL, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'x', 0, 'x', 0, 'x', 0,'x', 0,'x', 0, 'x', 0, 'x', 0
};