多种 USB 配置

Dirge. 2022-07-11 15:42:40 编辑

SetConfiguration 当有多个配置时,会让用户选择。

目前与windows的枚举过程 直接选择了第一个配置。如果有多个配置时,应该如何实现切换?

USB中文网 2022-07-11 16:39:52 编辑

Windows系统默认使用的是第0个配置,并且在代码中写死的。
以下是usbccgp.sys源码

 /*
     *  Get the first part of the configuration descriptor.
     *  It will tell us the size of the full configuration descriptor,
     *  including all the following interface descriptors, etc.
     */
    UsbBuildGetDescriptorRequest(&urb,
                                 (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0,                                    //DescriptorIndex
                                 0,
                                 (PVOID)&configDescBase,
                                 NULL,
                                 sizeof(USB_CONFIGURATION_DESCRIPTOR),
                                 NULL);
    status = SubmitUrb(parentFdoExt, &urb, TRUE, NULL, NULL);

并且REACTOS使用的代码也是这样的:

 Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);

该函数的源代码部分如下:


NTSTATUS
NTAPI
USBCCGP_GetDescriptor(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR DescriptorType,
    IN ULONG DescriptorLength,
    IN UCHAR DescriptorIndex,
    IN LANGID LanguageId,
    OUT PVOID *OutDescriptor)
{
...

    //
    // initialize urb
    //
    UsbBuildGetDescriptorRequest(Urb,
                                 sizeof(Urb->UrbControlDescriptorRequest),
                                 DescriptorType,
                                 DescriptorIndex,
                                 LanguageId,
                                 Descriptor,
                                 NULL,
                                 DescriptorLength,
                                 NULL);

    //
    // submit urb
    //
    Status = USBCCGP_SyncUrbRequest(DeviceObject, Urb);

所以,从代码上来看,windows没有支持USB的SET_CONFIGURATION的功能。
如果相要切换,一般是通过主机下发给设备一个切换命令,设备再次枚举,通过另一个配置描述来实现。
比如说一个UVC设备,通过UVC的扩展单元下发一个自定义命令,设备重新枚举,这时候枚举出来的是一个U盘,这里通过将需要升级的固件放到U盘中来升级。
当然,也可以使用别的方案,如自定义HID通讯。