怎么更专业的区分USB2.0设备工作在高速还是全速态?

USB中文网 2021-07-07 23:34:09 编辑

USB2.0设备一般工作在全速或高速态,但是怎么更专业的知道USB设备是工作在那种状态了?USB的一些描述符也没说啊。
当然,对于我们熟知的一些设备,如U盘,USB UVC摄像头这种对于带宽要求较高的设备,一般我们可以通过测试速率来算出来,而且这些设备一般是工作在高速态,但对于音频设备,这环境就有些复杂了,确实不好说。这里我们提供2种方法来判断USB设备的工作态

通过UsbTreeView来判断

UsbTreeView是一款运行在Windows环境下的专业软件,做USB开发的人应该都知道。通过这个软件们可以快速的知道USB连接在那个端口。
我们可以打开UsbTreeView,在左侧栏选中我们的USB设备,然后在右边的 connect inforamation中可以看到设备信息。

如于本人的U盘显示信息如下:

        --------------- Connection Information V2 -------------
Connection Index         : 0x04 (4)
Length                   : 0x10 (16 bytes)
SupportedUsbProtocols    : 0x04
 Usb110                  : 0 (no)
 Usb200                  : 0 (no)
 Usb300                  : 1 (yes)
 ReservedMBZ             : 0x00
Flags                    : 0x03
 DevIsOpAtSsOrHigher     : 1 (Is operating at SuperSpeed or higher)
 DevIsSsCapOrHigher      : 1 (Is SuperSpeed capable or higher)
 DevIsOpAtSsPlusOrHigher : 0 (Is not operating at SuperSpeedPlus or higher)
 DevIsSsPlusCapOrHigher  : 0 (Is not SuperSpeedPlus capable or higher)
 ReservedMBZ             : 0x00
Data (HexDump)           : 04 00 00 00 10 00 00 00 04 00 00 00 03 00 00 00   ................

USB耳机信息

        ---------------- Connection Information ---------------
Connection Index         : 0x08 (8)
Connection Status        : 0x01 (DeviceConnected)
Current Config Value     : 0x01
Device Address           : 0x0C (12)
Is Hub                   : 0x00 (no)
Device Bus Speed         : 0x01 (Full-Speed)
Number Of Open Pipes     : 0x02 (2 pipes to data endpoints)
Pipe[0]                  : EndpointID=4  Direction=IN   ScheduleOffset=0  Type=Interrupt
Pipe[1]                  : EndpointID=3  Direction=OUT  ScheduleOffset=0  Type=Isochronous
Data (HexDump)           : 08 00 00 00 12 01 00 02 00 00 00 40 D1 12 07 3A   ...........@...:
                           24 00 01 02 03 01 01 01 00 0C 00 02 00 00 00 01   $...............
                           00 00 00 07 05 84 03 03 00 01 00 00 00 00 09 05   ................
                           03 0D 40 02 01 00 00 00 00                        ..@....

USB摄像头

        ---------------- Connection Information ---------------
Connection Index         : 0x06 (6)
Connection Status        : 0x01 (DeviceConnected)
Current Config Value     : 0x01
Device Address           : 0x05 (5)
Is Hub                   : 0x00 (no)
Device Bus Speed         : 0x02 (High-Speed)
Number Of Open Pipes     : 0x01 (1 pipe to data endpoints)
Pipe[0]                  : EndpointID=3  Direction=IN   ScheduleOffset=0  Type=Interrupt
Data (HexDump)           : 06 00 00 00 12 01 01 02 EF 02 01 40 45 0C 1E 67   ...........@E..g
                           02 85 02 01 00 01 01 02 00 05 00 01 00 00 00 01   ................
                           00 00 00 07 05 83 03 10 00 06 00 00 00 00         ..............

通过Windows驱动

这玩意有就点复杂了,是通过USB的驱动获取的。在设备中通过向设备的总线发送IRP_MN_QUERY_INTERFACE IRP请求完成。

VOID
GetBusInterfaceVersion(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:
    This routine queries the bus interface version
Arguments:
    DeviceExtension
Return Value:
    VOID
--*/
{
    PIRP                       irp;
    KEVENT                     event;
    NTSTATUS                   ntStatus;
    PDEVICE_EXTENSION          deviceExtension;
    PIO_STACK_LOCATION         nextStack;
    USB_BUS_INTERFACE_USBDI_V1 busInterfaceVer1;
    //
    // initialize vars
    //
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    IsoUsb_DbgPrint(3, ("GetBusInterfaceVersion - beginsn"));
    irp = IoAllocateIrp(deviceExtension->TopOfStackDeviceObject->StackSize,
                        FALSE);
    if(NULL == irp) {
        IsoUsb_DbgPrint(1, ("Failed to alloc irp in GetBusInterfaceVersionn"));
        return;
    }
    //
    // All pnp Irp's need the status field initialized to
    // STATUS_NOT_SUPPORTED
    //
    irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    IoSetCompletionRoutine(irp,
                           (PIO_COMPLETION_ROUTINE) IrpCompletionRoutine,
                           &event,
                           TRUE,
                           TRUE,
                           TRUE);
    nextStack = IoGetNextIrpStackLocation(irp);
    ASSERT(nextStack);
    nextStack->MajorFunction = IRP_MJ_PNP;
    nextStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
    //
    // Allocate memory for an interface of type
    // USB_BUS_INTERFACE_USBDI_V0 and have the IRP point to it:
    //
    nextStack->Parameters.QueryInterface.Interface = 
                                (PINTERFACE) &busInterfaceVer1;
    //
    // Assign the InterfaceSpecificData member of the IRP to be NULL
    //
    nextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
    //
    // Set the interface type to the appropriate GUID
    //
    nextStack->Parameters.QueryInterface.InterfaceType = 
                                        &USB_BUS_INTERFACE_USBDI_GUID;
    //
    // Set the size and version of interface in the IRP
    // Currently, there is only one valid version of 
    // this interface available to clients.
    //
    nextStack->Parameters.QueryInterface.Size = 
                                    sizeof(USB_BUS_INTERFACE_USBDI_V1);
    nextStack->Parameters.QueryInterface.Version = USB_BUSIF_USBDI_VERSION_1;

    IsoUsb_IoIncrement(deviceExtension);
    ntStatus = IoCallDriver(DeviceObject,
                            irp);
    if(STATUS_PENDING == ntStatus) {
        KeWaitForSingleObject(&event,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        ntStatus = irp->IoStatus.Status;
    }
    if(NT_SUCCESS(ntStatus)) {
        deviceExtension->IsDeviceHighSpeed = 
                busInterfaceVer1.IsDeviceHighSpeed(
                                       busInterfaceVer1.BusContext);
        IsoUsb_DbgPrint(1, ("IsDeviceHighSpeed = %xn", 
                            deviceExtension->IsDeviceHighSpeed));
    }
    IoFreeIrp(irp);
    IsoUsb_DbgPrint(3, ("GetBusInterfaceVersion::"));
    IsoUsb_IoDecrement(deviceExtension);
    IsoUsb_DbgPrint(3, ("GetBusInterfaceVersion - endsn"));
}

参考资料:
http://www.verysource.com/code/14685402_1/isopnp.c.html
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/usbdlib/nf-usbdlib-usbd_createhandle

USB中文网 2022-03-27 22:54:52 编辑

大多数电子器件在设计的时候都要考虑电磁屏蔽和抗干扰的问题。所以,尽管USB3.0是有线信号,但仍然可能向外辐射电磁波,对其它信号产生干扰。

那么有人会问了,USB3.0不是5GHz吗?Wifi是2.4GHz怎么会有干扰呢?问题出在USB传输线上。
USB3.0的传输频率确实是5GHz串行,但USB3.0使用4条数据线组成2组,每组负责一个传输方向,实现全双工双向5GHz,而每条数据线的基准频率是2.5GHz。

所以,总带宽是5GHz没错,但每条线上是2.5GHz,这个频率距离2.4GWifi的频率太近了,又因为高频设备大多数都使用了SSC技术(扩频时钟?)使得信号不完全分布在一个固定频率上,所以就波及了2.5GHz附近的其它频率,所以对Wifi和蓝牙产生了较大的干扰。