当设备连接到USB主机时,该设备会向主机提供有关其功能和电压的信息。通常,设备通过一个描述符表提供这些信息。描述符表的值由开发人员定义,但所有描述符表都具有一组标准信息,用于描述设备属性和电压信息。比如,USB设备类(USB device class
)的规范规定:必须在设备描述符结构中包括该类必要的附加描述符信息。
设备描述符提供给主机一些信息,如设备符合的USB规范、设备支持的配置数量、支持的协议、制造商标识(VID
)、产品标识(PID
),以及序列号(如果有的话)。下表展示了设备描述符的结构:
偏移 | 域 | 大小(Bytes) | 描述 |
---|---|---|---|
0 | bLength | 1 | 设备描述符的长度(字节为单位) |
1 | bDescriptorType | 1 | 描述符的类型 |
2 | bcdUSB | 2 | 设备支持的USB版本(使用BCD码表示),如USB2.0为0x0200 |
4 | bDeviceClass | 1 | 设备的类 |
5 | bDeviceSubClass | 1 | 设备的子类 |
6 | bDeviceProtocol | 1 | 设备协议 |
7 | bMaxPacketSize0 | 1 | 端点0的最大包长度(8/16/32/64 Bytes) |
8 | idVendor | 2 | 制造商ID |
10 | idProduct | 2 | 产品ID |
12 | bcdDevice | 2 | 设备版本号(以BCD码描述) |
14 | iManufacturer | 1 | 制造商信息在USB描述符中的索引,不存在应置0 |
15 | iProduct | 1 | 产品信息在USB描述符中的索引,不存在应置0 |
16 | iSerialNumber | 1 | 序列号在USB描述符中的索引,不存在应置0 |
17 | bNumConfigurations | 1 | 设备可以支持的总配置数 |
bDeviceClass
,bDeviceSubClass
和bDeviceProtocol
:这些字段在USB设备枚举(插入并检测设备)过程中协助操作系统正确识别设备并加载适当的驱动程序。此外,它们还有助于避免不同接口(例如复合设备,一个物理设备包含多个逻辑设备)独立运作,确保设备的不同部分协同工作。大多数USB设备会在接口描述符中更详细地定义其类别,因此设备描述符中的这些字段通常为0x00,具体信息在接口描述符中提供。该描述符提供了有关特定设备配置的信息,例如接口数量、设备是否由总线供电或自供电、设备是否可以启动远程唤醒以及设备需要多少功率。下标为配置描述符的结构。
偏移 | 域 | 大小(Bytes) | 描述 |
---|---|---|---|
0 | bLength | 1 | 设备描述符的长度(字节为单位) |
1 | bDescriptorType | 1 | 描述符的类型 |
2 | wTotalLength | 2 | 配置描述符的接口和端点描述符的总长度 |
4 | bNumInterfaces | 1 | 配置中的接口总数 |
5 | bConfigurationValue | 1 | 配置值(给SET_CONFIGURATION使用的来选择此配置的值) |
6 | iConfiguration | 1 | 描述此配置的字符串的索引 |
7 | bmAttributes | 1 | Bit7:保留(默认为1) Bit6:0-总线供电 1-自供电 Bit5:0-支持远程唤醒 1-不支持远程唤醒 |
8 | bMaxPower | 1 | 设备全速运行时消耗的最大功率(2mA为单位) |
这个描述符描述了与单个设备功能相关联的两个或多个接口。接口关联描述符通知主机这些接口是连接在一起的。例如,USB串口有两个与之相关联的接口:一个控制接口和一个数据接口。该描述符告诉主机这两个接口属于同一个功能,并属于通信设备类(CDC
)。并非在所有情况下都需要此描述符。下图显示了单个接口与单个设备功能的一一对应的关系,这种情况使用接口描述符就行(1.4介绍):
下显示了两个独立的接口与特定设备功能相关联的情况,这种情况需要使用接口关联描述符:
下表为接口关联描述符的组成:
偏移 | 域 | 大小(Bytes) | 描述 |
---|---|---|---|
0 | bLength | 1 | 设备描述符的长度(字节为单位) |
1 | bDescriptorType | 1 | 描述符的类型 |
2 | bFirstInterface | 1 | 与该功能相关联的第一个接口的编号 |
3 | bInterfaceCount | 1 | 与该功能相关联的连续接口的数量(即第一个开始数后面连续多少个) |
4 | bFunctionClass | 1 | 类别码 |
5 | bFunctionSubClass | 1 | 子类码 |
6 | bFunctionProtocol | 1 | 协议码 |
7 | iFunction | 1 | 该功能的字符串描述符索引 |
接口描述符描述了配置中的特定接口,此描述符中确定了接口的端点数量,声明了设备的USB类,供主机加载适合适驱动程序。
偏移 | 域 | 大小(Bytes) | 描述 |
---|---|---|---|
0 | bLength | 1 | 设备描述符的长度(字节为单位) |
1 | bDescriptorType | 1 | 描述符的类型 |
2 | bInterfaceNumber | 1 | 该接口在特定USB配置中的索引 |
3 | bAlternateSetting | 1 | 描述接口的不同配置或操作模式(可理解为功能复用) |
4 | bNumEndpoints | 1 | 此接口使用的端点数量(不包括端口0) |
5 | bInterfaceClass | 1 | 接口类 |
6 | bInterfaceSubclass | 1 | 接口子类 |
7 | bInterfaceProtocol | 1 | 接口协议 |
8 | iInterface | 1 | 描述此接口的字符串索引 |
设备中使用的每个端点都有自己的描述符。这个描述符提供了主机必须具备的有关端点的信息,包括端点的方向、传输类型和最大数据包大小。如下图所示:
偏移 | 域 | 大小(Bytes) | 描述 |
---|---|---|---|
0 | bLength | 1 | 设备描述符的长度(字节为单位) |
1 | bDescriptorType | 1 | 描述符的类型 |
2 | bEndpointAddress | 1 | bit[3:0]:端点号 bit[6:4]:保留,默认为0 bit[7]:方向,0-out 1-IN,控制端点将忽略此字段 |
3 | bmAttributes | 1 | bit[1:0]:传输类型,00-控制,01-等时,10-批量,11-中断 如果是等时端点,bit[5:2]的定义如下(若不是下面字段则忽略): bit[3:2]:同步类型,00-不同步,01-异步,10-自适应,11-同步 bit[5:4]:使用类型,00-数据端点,01-反馈端点,10-隐式反馈数据端点,11-保留 |
4 | wMaxPacketSize | 2 | 该端点的最大数据包大小 |
6 | bInterval | 1 | 中断端点的轮询间隔,以毫秒为单位(等时端点为1,控制或批量端点则该字段忽略) |
字符串描述符是可选描述符,用于提供有关设备的用户可读信息。描述符中可能包含设备的名称、制造商、序列号,以及各个接口或配置的名称等信息。如果设备未使用字符串,前面提到的描述符中的任何字符串索引字段必须设置为00h。
这些字符串是使用UNICODE UTF16LE编码定义的,可以支持多种语言(每个语言有一个语言标识码)。在Windows系统中,这些字符串可以在设备管理器中查看。下表展示了字符串描述符的结构。
偏移 | 域 | 大小(Bytes) | 描述 |
---|---|---|---|
0 | bLength | 1 | 设备描述符的长度(字节为单位) |
1 | bDescriptorType | 1 | 描述符的类型 |
2…n | bString/wLangID | 不定 | unicode编码的字符串或语言标识码 |
字符串描述符有两种可能的形式。第一个字符串描述符包含语言ID的值,即wLangID
,其中包含一个或多个两字节的ID代码,指示字符串所用的语言。USB-IF提供了定义许多不同ID代码的文档。例如,美国英语的ID代码是0409h。wLangID
之后的所有字符串描述符都使用bString
字段,它是一个包含Unicode字符串(UTF16LE
)的字符串字段,每个字符使用2个字节表示。
1、报告描述符(Report Descriptors
):USB设备类可能需要扩展的描述符信息。开发者必须确保USB设备类所需的任何额外描述符信息包含在描述符文件中。例如,对于HID类,开发者必须包括进一步定义设备属性的报告描述符。
2、MS OS描述符(MS OS Descriptor
):微软有一个名为Microsoft OS Feature Descriptor的描述符,用于供应商特定的设备。该描述符提供了与Microsoft Windows有关的特定信息,如特殊图标、注册表设置、帮助文件和URL。
3、设备限定符描述符(Device Qualifier Descriptor
):它描述了高速USB设备的信息,如果设备以另一速度运行,该描述符将发生更改,这在支持两种速度配置的设备中是必需的。如果设备当前以全速运行,这个描述符将提供关于设备在高速模式下可能运行的方式或特性的信息。同样,如果在设备以高速运行时请求此描述符,描述符读取将告诉主机有关全速配置的信息。如果请求此描述符并且设备仅支持全速,适当的操作是返回STALL。否则,将根据请求提供描述符信息。
4、BOS描述符(BOS Descriptor
):在支持链接电源管理(Link Power Management
)的USB 2.0设备中,还有一个二进制设备对象存储(Binary device Object Store
,BOS
)描述符。只有支持LPM功能的PSoC设备家族中的PSoC 4200L设备支持BOS描述符。LPM是USB暂停模式的改进,允许设备以微秒级的转换延迟进入和退出低功耗模式,而不是与暂停模式进入/退出相关的3-20毫秒的延迟。
USB设备只有一个设备描述符。然而,一个设备可以拥有多个配置、接口、端点和字符串描述符。当一个设备进行枚举时,最后的阶段之一是读取设备描述符并决定启用哪个设备配置。一次只能启用一个配置。例如,一个设计中可以有一个在设备自供电时使用的配置,以及一个在设备由外部总线供电时使用的配置。自供电设备和总线供电设备的整体USB功能可能不同,多个配置和多个配置描述符就能实现这种切换。
同时,一个设备可以拥有多个接口,因此也有多个接口描述符。一个拥有多个执行不同功能的接口的USB设备被称为复合设备(composite device
)。比如在USB耳机中,USB设备拥有两个接口:一个用于耳机的音频功能,另一个用于音量调节的控制。多个接口可以同时处于活动状态。下图显示了在单个USB设备但有两个接口的情况:
每个接口可以拥有多个配置,这些多个配置称为备用设置(alternate settings
)。例如,在一个备用设置中,设备的端点可以配置为批量(bulk
),而在另一个备用设置中,端点可以配置为等时(Isochronous
)。如下图所示:
下图显示了用于创建高度可定制的USB设备的定制选项的总体示意图,以适应各种配置选项
USB开发者论坛有一个被承认和批准的USB设备类列表。最常见的设备类包括:
Human Interface Device
,HID
)Mass Storage Device
,MSD
)Communication Device Class
,CDC
)Vendor Specific
,特定尝试开发的USB类)在开发特定类的应用程序时,需要考虑几个因素。首先,每个类都有固定的最大带宽。其次,每个类别都有对支持的传输类型和必须支持的特定命令的限制。使用这些被承认的USB设备类别的最大优势是在各种操作系统上实现跨平台支持。
在上一节的USB描述符部分,USB设备类的定义在:设备描述符的第四个字节和接口描述符的第六个字节。USB规范定义了许多不同的USB类以及与之相关的设备类代码,如下表所示:
类代码 | 用途(即类信息的使用范围) | 描述 | 例子 |
---|---|---|---|
00h | 设备 | 未定 | 当设备类别未指定时,接口描述符用于确定所需的驱动程序 |
01h | 接口 | 音频 | 扬声器、麦克风、声卡、MIDI |
02h | 设备/接口 | 通信和CDC控制 | 调制解调器、以太网适配器、Wi-Fi适配器 |
03h | 接口 | HID(Human Interface Device) | 键盘、鼠标、摇杆 |
05h | 接口 | PID(Physical Interface Device) | 力反馈操纵杆 |
06h | 接口 | 图像 | 摄像机、扫描仪 |
07h | 接口 | 打印 | 打印机、计算机数控机器 |
08h | 接口 | 大容量存储 | 外部硬盘、闪存驱动器、存储卡 |
09h | 设备 | USB集线器 | USB集线器 |
0Ah | 接口 | CDC数据 | 与上面的02h类一起使用 |
0Bh | 接口 | 智能卡 | USB智能卡读取器 |
0Dh | 接口 | 信息安全 | 指纹读取器 |
0Eh | 接口 | 视频 | 网络摄像头 |
0Fh | 接口 | 个人健康护理 | 心跳监测器、血糖仪 |
DCh | 设备/接口 | 诊断设备 | 测试USB设备是否符合USB标准/规范的设备 |
E0h | 接口 | 无线控制器 | 蓝牙适配器 |
EFh | 设备/接口 | 杂项 | 如微软的ActiveSync :同步手机和电脑数据的APP |
FEh | 接口 | 应用特定的 | 红外桥接器、测试与测量类,USB DFU(直接固件更新,即通过USB升级固件) |
FFh | 设备/接口 | 供应商特定的 | 表示一个设备需要供应商特定的驱动 |