USB协议-描述符篇(一)

1.USB描述符简介

USB描述符,即使用描述符报告它们的属性。 描述符是一个具有定义格式的数据结构。 每个描述符都以一个字节宽字段开始,该字段包含描述符中的总字节数,然后是一个标识描述符类型的字节宽字段。

描述符主要包含两大类:1,标准描述符,每个USB设备都要有;2,特殊类描述符,是针对类Class进行专有的描述符, 比如:UVC类设备,在标准描述符的基础上还需要有视频控制接口描述符、视频控制端点描述符、视频流接口描述符、视频流端点描述符

使用描述符允许对单个配置的属性进行简明的存储,因为每个配置可以重用来自具有相同特征的其他配置的描述符或描述符的一部分。 以这种方式,描述符类似于关系数据库中的单个数据记录。

在适当的情况下,描述符包含对字符串描述符的引用,这些描述符以人类可读的形式提供描述描述符的可显示信息。 包含字符串描述符是可选的。 但是,描述符中的引用字段是强制性的。 如果设备不支持字符串描述符,则字符串引用字段应重置为零以指示没有可用的字符串描述符。

如果描述符返回其长度字段中的值小于本规范定义的值,则该描述符无效并应被主机拒绝。 如果描述符返回的长度字段中的值大于本规范定义的值,则主机将忽略额外的字节,但使用返回的长度而不是预期(规范约定)的长度来定位下一个描述符

设备可以通过两种方式返回 class- or vendor-specific descriptors:
1,如果class-或vendor-specific描述符使用与标准描述符相同的格式(例如,以长度字节开始,然后是类型字节),则它们应与 GetDescriptor(Configuration) 请求返回的配置信息中的标准描述符交错返回 . 在这种情况下,class或vendor-specific的描述符应遵循它们修改或扩展相关标准的描述符
2,如果class-或vendor-specific描述符独立于配置信息或使用非标准格式,则指定class-或vendor-specific描述符类型和索引的 GetDescriptor() 请求可用于从设备检索描述符。 class-或vendor-specific规范将定义检索这些描述符的适当方法。

2.USB标准描述符

USB standard descriptors主要包含以下几种描述符:

  • device descriptor 设备描述符, 一个usb设备只能有一份设备描述符
  • configuration descriptor 配置描述符,一份设备描述符可以包含多个配置描述符,通常情况下只有一份
  • interface descriptor 接口描述符,一份配置描述符可以包含多个接口描述符,每个接口会有多个alternateSetting备选接口
  • endpoint descriptor 端点描述符,一份接口描述符中会包含多个端点
  • string descriptor 字符描述符

这些描述符在协议中每个都定义了对应的字段, 每个字段占用几个字节都有约定, 最终在代码中表现的都是一个个对应的数据结构类型。每个数据类型都会和相应的描述符一一对应。
下面我们就对每个描述符都有哪些属性进行一一列举。

2.1 设备描述符

设备描述符是USB主机枚举USB设备申请的第1个描述符,每个设备有且仅有一个设备描述符,也就是大家以后看到的任何的USB设备都只有一个设备描述符数组,设备描述符的长度是固定18个字节,下面我们来学习设备描述符数据结构,看看USB设备具有哪些特征,它的结构我们可以通过下面的表格来逐一了解。

OffsetFieldSizeValueDescription
0bLength1Number描述符的全部长度
1bDescriptorType1Constant指描述符的类型,设备描述符该值0x01
2bcdUSB2BCDUSB协议版本号,一个二进制编码十进制的 USB 规范版本号(即 2.10 是 210H)。 该字段标识设备及其描述符符合的 USB 规范的版本。
4bDeviceClass1ClassClass code (assigned by the USB-IF).
如果此字段重置为零,则在配置描述符集合中的每个接口描述符中都要指定自己的类信息,并且各个接口独立运行; 如果该字段设置为 1 到 FEH 之间的值,则设备在不同的接口上支持不同的类规范,接口可能无法独立运行; 此值标识用于聚合接口的类定义,对于应该是设置0, 还是1到FEH之间的值,是根据defined-class-codes中的类代码Descriptor Usage的描述约定进行设置的。
如果此字段设置为 FFH,则设备类是特定于供应商的,代表用户自定义数据传输类别。
5bDeviceSubClass1SubClassSubclass code (assigned by the USB-IF).
这些代码由 bDeviceClass 字段的值限定。
如果 bDeviceClass 字段重置为零,则该字段也应重置为零。 如果 bDeviceClass 字段未设置为 FFH,则所有值都是保留供 USB-IF 分配。
6bDeviceProtocol1ProtocolProtocol code (assigned by the USB-IF).
这些代码由 bDeviceClass 和 bDeviceSubClass 字段的值限定。 如果设备支持基于设备而不是基于接口的特定于类的协议,则此代码标识设备使用的协议,如设备类规范所定义。 如果此字段重置为零,则设备不会在设备基础上使用特定于类的协议。 但是,它可以在接口基础上使用特定于类的协议。 如果此字段设置为 FFH,则设备基于设备使用特定于供应商的协议。
7bMaxPacketSize01Number端点零的最大数据包大小。(仅8,16,32,64为合法值)
8idVendor2IDVendor ID (assigned by the USB-IF)
10idProduct2IDProduct ID (assigned by the manufacturer)
12bcdDevice2BCD设备发行号(BCD码) in binary-coded decimal
14iManufacturer1Index描述厂商字符串字符索引
15iProduct1Index描述产品字符串索引
16iSerialNumber1Index产品序列号字符串索引
17bNumConfigurations1Number可能的配置描述符的数量

2.2 配置描述符

配置描述符描述有关特定设备配置的信息。该描述符包含bConfigurationValue字段,该字段的值在用作SetConfiguration()请求的参数时,使设备采用所描述的配置。

描述符描述了配置提供的接口数量。每个接口可以独立运行。例如,ISDN设备可能配置有两个接口,每个接口提供64 Kb / s双向信道,在主机上具有单独的数据源或接收器。另一种配置可能将ISDN设备作为单个接口,将两个信道绑定到一个128 Kb / s双向信道。

当主机请求配置描述符时,将返回所有相关的接口和端点描述符。

一个USB设备至少有一个或者多个配置,这一点可以从设备描述符的最后一项bNumConfigurations得到,但是当前只能选择其中一种配置,每一种配置都对应一个配置描述符集合,为什么说是一个集合呢,因为这个配置包括标准配置描述符、接口描述符、端点描述符,如果是UVC设备还会包括UVC描述符,我们今天讲的是标准配置描述符,后期会讲解其他的描述符。标准配置描述符只有9个字节,组成如下:

OffsetFieldSizeValueDescription
0bLength1Number描述符的全部长度
1bDescriptorType1Constant指描述符的类型,配置描述符该值为0x02
2wTotalLength1Number此配置信息的总长(包括配置,接口,端点和设备类及厂商定义的类特定描述符)
4bNumInterfaces1Number此配置所支持的接口个数
5bConfigurationValue1Number用作 SetConfiguration()函数请求的参数值,用来选择哪一个配置。
比如在设备描述符中bNumConfigurations 的值为3,说明有三个配置, 那么设备应该选用哪个配置呢, bConfigurationValue 这个属性的值就告诉了当前的配置描述符在3个配置描述符中的索引值编号。可以通过SetConfiguration()进行切换选择配置
6iConfiguration1Index描述此配置的字串串描述表的索引
7bmAttributes1bitsmap配置特性:
D7: 保留(设为一)
D6: 自给电源
D5: 远程唤醒
D4…0:保留(设为一)
一个既用总线电源又有自给电源的设备会在MaxPower域指出需要从总线取的电量。并设置D6为一。运行时期的实际电源模式可由GetStatus(DEVICE) 请求得到。
8bMaxPower1mA在此配置下的总线电源耗费量。以 2mA 为一个单位。

注意:
第一次只获取配置描这符的基本长度9字节,获取后从wTotalLength字节中解析出配置描述符的总长度,然后再次获取全部的描述符。 全部的描述符包含接口、端点及类设备特有的描述符。

2.3 接口描述符

首先要明确的一点是:接口描述符不能单独返回USB主机,必须跟在配置描述符后面返回。一般情况是配置描述符是一个集合,配置描述符集合主要由标准配置描述符、接口描述符、端点描述符、(类描述符, 如HID、UVC、CDC等类功能的描述符),报告描述符和物理描述符单独返回给主机。
接口描述符包含9个字节,组成如下:

OffsetFieldSizeValueDescription
0bLength1Number描述符的全部长度
1bDescriptorType1Constant指描述符的类型,接口描述符该值0x04
2bInterfaceNumber1Number接口编号。如果一个配置有多个接口的话,那么每个接口的编号都有一个独立的编号,编号从0开始递增。如果只有一个接口这里可以设置为0, 如果不只一个接口,从0开始依次递增
3bAlternateSetting1Number备用接口编号,一般很少用,设置为0。即,比如一个接口1中可能有多种备选接口进行选择,这个字段就是用来标识在接口1中我是第几个备选接口,也是从0开始依次递增。 如果没有备选接口该值为0。通常UVC设备都会有备选接口。
4bNumEndpoints1Number该接口使用的端点个数,前面讲过一个接口就是一种功能,每个接口需要用户为其分配端点来实现对应的功能,注意一点,这个端点个数不包括端点0
5bInterfaceClass1ClassClass code (assigned by the USB-IF).
零值保留用于将来的标准化。 如果此字段设置为 FFH,则接口类是特定于供应商的进行自定义。 所有其他值保留供 USB-IF 分配。该值取自defined-class-codes约定的值。通常USB设备是作为UVC、HID等功能都是这个字段进行定义的。
6bInterfaceSubClass1SubClassSubclass code (assigned by the USB-IF).
这些代码由 bInterfaceClass 字段的值限定。 如果 bInterfaceClass 字段重置为零,则该字段也应重置为零。 如果 bInterfaceClass 字段未设置为 FFH,则所有值都保留供 USB-IF 分配。 目前只有一个接口子类,就是0x02.
7bInterfaceProtocol1ProtocolProtocol code (assigned by the USB).
这些代码由 bInterfaceClass 和 bInterfaceSubClass 字段的值限定。 如果接口支持特定于类的请求,则此代码标识设备使用的协议,如设备类的规范所定义。 如果此字段重置为零,则设备不会在此接口上使用特定于类的协议。 如果此字段设置为 FFH,则设备为此接口使用供应商特定的协议。
8iInterface1index描述此接口的描述索引值

2.4 端点描述符

端点描述符包含主机要确定每个端点的带宽要求所需要的信息。
首先要明确的一点是端点描述符也不能单独返回给USB主机,主机会请求获得配置描述符集合,配置描述符集合主要由标准配置描述符、接口描述符、端点描述符、类描述符,报告描述符和物理描述符是单独返回给USB主机。
端点描述符包含7个字节,组成如下:

OffsetFieldSizeValueDescription
0bLength1Number描述符的全部长度
1bDescriptorType1Constant指描述符的类型,端点描述符该值0x05
2bEndpointAddress1Endpoint该字段描述usb设备上端点的地址。 该地址有以下编码:
Bit 3…0: The endpoint number
Bit 6…4: Reserved, reset to zero
Bit 7: Direction, ignored for control endpoints
    0 = OUT endpoint
    1 = IN endpoint
3bmAttributes1Bitmap当使用 bConfigurationValue 配置端点时,该字段描述端点的属性。
Bits 1…0: Transfer Type
     00 = Control
     01 = Isochronous
     10 = Bulk
     11 = Interrupt
如果是中断端点,位 5…2 定义如下:
Bits 3…2: Reserved
Bits 5…4: Usage Type
     00 = Notification
     01 = Periodic
     10 = Reserved
     11 = Reserved
如果是同步的,它们的定义如下:
Bits 3…2: Synchronization Type
     00 = No Synchronization
     01 = Asynchronous
     10 = Adaptive
     11 Synchronous
Bits 5…4: Usage Type
     00 = Data endpoint
     01 = Feedback endpoint
     10 = Implicit feedback Data endpoint
     11 = Reserved
如果不是等时或中断端点,位 5…2 被保留并且应设置为零。所有其他位都保留并应重置为零。 保留位主机将忽略。
4wMaxPacketSize2Number表示当前配置下此端点能够接收或发送的最大数据包的大小。
该字段只有两个合法值。 对于控制端点,此字段应设置为 512。对于所有其他端点类型,此字段应设置为 1024。
6bInterval1Number查询时间,就是主机多久和设备通讯一次,主机在枚举设备的时候会得到端点描述符,然后根据端点描述符这个值和此端点进行对应的数据交互,也就是主机多久给端点发送一次数据请求。根据设备运行速度以帧或微帧表示,低速和全速称为帧,下面的一个值代表1ms,高速称为微帧,一个值代表125us。

2.5 字符串描述符

字符串描述符就是用字符串描述一个设备的一些属性,毕竟人能看懂的是字符,而不是十六进制,描述的属性包括设备厂商名字、产品名字、产品序列号、各个配置名字、各个接口名字,还有就是由我们用户自己定义的字符串,说白了就是起名字,让人们一看就知道这个设备是什么设备,字符串描述符对于设备来说是可选的。

在这里插入图片描述

3.特殊类描述符

该描述符是指定具体设备类定义的专有(私有)描述符。比如HID设备、CDC设备、UVC类设备等都有自己的专有描述符。 具体需要查找对应类规范。

4.USB类定义

USB 定义了类代码信息,用于识别设备的功能并根据该功能在名义上加载设备驱动程序。 该信息包含在三个字节中,名称分别为 Base Class、SubClass 和 Protocol。 (请注意,本说明中使用“基类”来标识类代码三元组的第一个字节。USB 规范中未使用该术语)。 一个设备上有两个地方可以放置类代码信息,一个在Device Descriptor,一个在Interface Descriptors。 一些定义的类代码只允许在设备描述符中使用,其他的可以在设备和接口描述符中使用,有些只能在接口描述符中使用。 下表显示了当前定义的一组基类值、通用用途是什么以及可以使用基类的位置(设备或接口描述符或两者)。

Base ClassDescriptor UsageDescription
00hDeviceUse class information in the Interface Descriptors
01hInterfaceAudio
02hBothCommunications and CDC Control
03hInterfaceHID (Human Interface Device)
05hInterfacePhysical
06hInterfaceImage
07hInterfacePrinter
08hInterfaceMass Storage
09hDeviceHub
0AhInterfaceCDC-Data
0BhInterfaceSmart Card
0DhInterfaceContent Security
0EhInterfaceVideo
0FhInterfacePersonal Healthcare
10hInterfaceAudio/Video Devices
11hDeviceBillboard Device Class
12hInterfaceUSB Type-C Bridge Class
DChBothDiagnostic Device
E0InterfaceWireless Controller
EFhBothMiscellaneous
FEhInterfaceApplication Specific
FFhBothVendor Specific

5.USBDescriptorType

每个描述符都有一个共同的header field:

  • bLength
  • bDescriptorType
    其中bDescriptorType 的值就是用来确定当前的描述符是哪一种。
    主要的描述符类别如下:
DescriptorTypeValue
DEVICE1
CONFIGURATION2
STRING3
INTERFACE4
ENDPOINT5
DEVICE_QUALIFIER6
OTHER_SPEED_CONFIGURATION7
INTERFACE_POWER8
OTG9
DEBUG10
INTERFACE_ASSOCIATION11

参考文档:usb协议文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值