上一篇文章说了USB设备描述符,这一篇咱们看下USB的配置描述符。关于配置描述符,我们需要知道三点:
1、一个USB设备可以有多种配置,这一点可以从设备描述符的最后一项得到:
bNumConfigurations:可能的配置数,一般单一设备该值都是1.
2、一个USB设备至少要有一个配置描述符。
3、配置描述符不会单独发送给USB主机,通常会以集合的形式发送给主机。集合通常包含:配置描述符,接口描述符,端点描述符,HID描述符。这几个描述符组成一个大数组。
相比设备描述符,配置描述符短一些,只有9个字节,含义也比较好理解。我们看下面的表格:
偏移量 | 名称 | 大小 | 说明 |
0 | bLength | 1 | 描述符长度(9字节) |
1 | bDescriptorType | 1 | 描述符类型(配置描述符为0x02) |
2 | wTotalLength | 2 | 配置描述符集合总长度 |
4 | bNumInterfaces | 1 | 配置支持的接口数 |
5 | bConfigurationValue | 1 | 配置的值 |
6 | iConfiguration | 1 | 描述该配置的字符串的索引值 |
7 | bmAttributes | 1 | 该设备的属性 |
8 | bMaxPower | 1 | 设备所需的电流(单位是2ma) |
9个字节,包含8项内容,而且表格描述也很清晰。我们简单看下:
bLength,很简单,不解释。
bDescriptorType,描述符类型,也很简单。看到这里,你会发现,这个描述符的结构和设备描述符结构开头是一样的,都是先说描述符长度,然后说类型。
总共有哪些描述符,依然通过代码可以知道:
#define USB_DESC_TYPE_DEVICE 0x01U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_STRING 0x03U
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_BOS 0x0FU
wTotalLength,配置描述符集合总长度,也就是说总共有多少个字节。前面说了,配置描述符不会单独发给USB主机,是以集合的形式,集合里包含了:配置描述符,接口描述符,端点描述符,HID描述符。
所以,这就是个数数的问题。
bNumInterfaces,接口数。一般来说,单一设备只有一个接口,如鼠标;如果是复合设备,如带鼠标功能的键盘,那它可能有两个接口(为什么措辞是“可能”,而不是“肯定”,根据实现方法不一样)。
bConfigurationValue,配置的值。一个USB设备可以有多个配置,配置值就是每个配置的标识。设置配置请求时,会发送配置值。如果发送的值和这里值一样,说明这个值被激活。关于这一点,需要结合USB标准请求结构来理解。后续会说明。
iConfiguration,描述该配置的字符串的索引值,如果没有字符串,那这个值就是0.
bmAttributes,本设备的属性。D7是保留位,默认为1;D6表示供电方式,0是自供电,1是总线供电;D5表示是否支持远程唤醒;D4~D0保留,默认为0.
bMaxPower,设备需要的电流,单位是2ma。如果一个设备耗电量100ma,那么本子节就设置为50即可。
下面看一段STM32中配置描述符的代码:
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_HID_CONFIG_DESC_SIZ,
/* wTotalLength: Bytes returned */
0x00,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
对照看一下,你会发现很好理解。
好了,打完收工!
bmAttributes,关于供电模式写错了吧,1表示总线供电,0表示自供电
确实写错了,这个地方写错是因为我参照的圈圈的书里的讲解,但是对比了STM32的配置描述符之后,发现是圈圈的书写错了