怎么更专业的区分USB2.0设备工作在高速还是全速态?
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
大多数电子器件在设计的时候都要考虑电磁屏蔽和抗干扰的问题。所以,尽管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和蓝牙产生了较大的干扰。