USB配置描述符实现设备的不同功能或者类协议版本
USB规范设计灵活,通过不同的配置可以实现同一个USB设备实现不同的功能。
不同的配置描述符
USB规范中,对于同一个USB设备,由于主机或者连接线缆的原因,表现不同的速度。
如对于USB2.0一般会区分高速和全速情况,对于USB3.0会区分USB3.0和USB2.0的情况。这种同一设备因设备在主机端枚举过程中表现不同的速率问题,主要是通过其它速率配置描述符和设备限定描述符来实现的。另外,由于设备端其知道其与主机端的协商的结果,故也可以通过上报不同的配置描述符来实现。另一个广泛的使用领域就是有的设备需要区分操作系统的不同而表现上报不同的配置描述符。更有甚有的厂商在此的基础上扩展的更加广泛,加载系统默认的驱动时表现为默认的设备类型,当加载自己厂商的情况下,切换为其指定的设备类型。
这一切都是通过上报不同的配置描述符来实现的。
以上的情况无论怎么变,设备上报其只有一个配置描述符。
多个配置描述符
另一种情况是设备通过设备描述符的bNumConfigurations字段上报给主机其由有多个配置描述符。通过GET_DESCIRPTOR获取这几个配置描述符并解析之后,通过SET_CONFIGURATION来选择一个其支持的配置描述符。
如我们有一个USB相机,其既支持最新UVC1.5版本用于提供用户最优的体验,但又为了兼容老的操作系统需要支持UVC1.0。
设备通过配置描述符bNumConfigurations=0x02上报给主机。该设备可以具有多个配置描述符以支持UVC 1.5或UVC 1.0。主机可以选择特定的配置描述符,或者扫描整个可用的配置描述符并选择最合适的配置描述符。
设备描述符
===>Device Descriptor<===
bLength: 0x12
bDescriptorType: 0x01
bcdUSB: 0x0200
bDeviceClass: 0xEF
bDeviceSubClass: 0x02
bDeviceProtocol: 0x01
bMaxPacketSize0: 0x40 = (64) Bytes
idVendor: 0x046D
idProduct: 0x0823
bcdDevice: 0x0010
iManufacturer: 0x00
iProduct: 0x00
iSerialNumber: 0x00
bNumConfigurations: 0x02
注意这里的bNumConfigurations: 0x02
第一个配置描述符-UVC1.0
bConfigurationValue=0x01
===>Configuration Descriptor<===
bLength: 0x09
bDescriptorType: 0x02
wTotalLength: 0x0CC2
bNumInterfaces: 0x04
bConfigurationValue: 0x01 (first configuration)
iConfiguration: 0x00
bmAttributes: 0x80
MaxPower: 0xFA
===>Class-Specific Video Control Interface Header Descriptor<===
bLength: 0x0D
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bcdUVC: 0x0100 (UVC Version 1.0)
wTotalLength: 0x00BD
dwClockFrequency: 0x02DC6C00
bInCollection: 0x01
baInterfaceNr[1]: 0x01
...
第二个配置描述符-UVC1.2
bConfigurationValue=0x02
===>Configuration Descriptor<===
bLength: 0x09
bDescriptorType: 0x02
wTotalLength: 0x0CC2
bNumInterfaces: 0x04
bConfigurationValue: 0x02 (second configuration)
iConfiguration: 0x00
bmAttributes: 0x80
MaxPower: 0xFA
===>Class-Specific Video Control Interface Header Descriptor<===
bLength: 0x0D
bDescriptorType: 0x24
bDescriptorSubtype: 0x01
bcdUVC: 0x0150 (UVC Version 1.5)
wTotalLength: 0x00BD
dwClockFrequency: 0x02DC6C00
bInCollection: 0x01
baInterfaceNr[1]: 0x01
...