在USB总线接口协议中,对于USB外部设备功能特征是通过端点(Endpoint)、配置(Configuration)和接口(Interface)来描述的,这些就是典型的USB描述符。
USB主机通过设备请求来读取外部设备的USB描述符,可以掌握该设备的接口信息和功能。USB设备请求提供了USB设备描述符的读取和写操作,包括标准设备请求和自定义请求两种。USB描述符和USB设备请求是USB外设的主要内容,是USB设备功能的体现。
本章包括
USB各种描述符的定义
USB各类设备请求的格式
USB设备请求范例
一、USB描述符概述
在USB总线接口协议中,规定了一些标准的USB描述符,如表所示。对于USB设备来说,有些USB描述符是必须的,例如设备描述符、配置描述符、字符串描述符、接口描述符和端点描述符。其余一些描述符并非必须,只在特定USB设备中使用,例如设备限定描述符和其他速率配置描述符用于高速USB设备,OTG设备描述符用于USBOTG外设,而超高速端点伴侣描述符用于超高速USB设备等等。
USB描述符其实就是一个数据集合,用来表征USB设备某一方面的功能。USB协议中严格规定了每一种描述符的数据格式。各个USB描述符均由一系列具有固定排列顺序的字段构成。通常来说,bLength为第一个字段,表示该描述符的长度;bDescriptorType为第二个字段,表示该描述符的类型。在描述符的定义中,往往采用特定的前缀字符来表示该字符的类型和长度,包括如下几类:
前缀字符b:表示一个字节(8b);
前缀字符w:表示一个字(16b);
前缀字符bm:表示按位寻址;
前缀字符bcd:表示采用二进制编码的10进制数;
前缀字符i:表示索引值;
前缀字符id:表示标识码。
USB描述符是深入学习USB开发所必须首要掌握的。
二、设备描述符(Device)
USB设备描述符是每个USB设备所必需包含的,并且一个USB设备只能有一个设备描述符。USB设备描述符用于表示USB设备的总体信息,包括USB规范版本号、产品ID、供应商ID、设备版本号等信息。USB设备描述符中的信息对于整个设备是完全有效的,而无关配置和接口的数量。
1、设备描述符定义
USB设备描述符由14个字段按照固定的顺序组成,该描述符的总长度固定为18个字节。USB设备描述符各个字段的格式,如表7.2所示。
下面详细说明USB设备描述符各个字段的具体含义:
1.bLength字段
bLength字段用于表示USB设备描述符的长度,长度占用1个字节,地址偏移量为0。对于USB设备描述符来说,bLength字段的值固定为18,也就是12H。
2.bDescriptorType字段
bDescriptorType字段用于表示USB描述符的类型值,长度占用1个字节,地址偏移量为1。对于USB设备描述符来说,bDescriptorType字段的值固定为01H。
3.bcdUSB字段
bcdUSB字段用于表示该USB设备所遵循的USB规范版本号,长度占用2个字节,地址偏移量为2。bcdUSB字段以BCD码的形式表示,其格式为0xAABC,这里各个符号的含义如下:
AA:主版本号。
B:次版本号。
C:子次版本号。例如,对于高速USB设备来说,其版本为USB2.0,对应的bcdUSB字段设置为0200H。
4.bDeviceClass字段
bDeviceClass字段用于表示该USB设备所属的标准设备类,长度占用1个字节,地址偏移量为4。bDeviceClass字段的值代表了不同的设备类:bDeviceClass字段值在01~FEH之间的时候,表示该设备为USB协议中预定义的某个标准设备类,例如03H表示HID设备类。bDeviceClass字段为0时,表示USB设备包含多个接口,各个接口互相独立,分别属于不同的设备类。此时,需要在USB固件接口描述符中进一步定义。bDeviceClass字段为FFH时,表示由用户自定义该设备类的类型。
5.bDeviceSubClass字段
bDeviceSubClass字段用于表示USB设备所属的标准设备子类,长度占用1个字节,地址偏移量为5。
bDeviceSubClass字段主要用于对USB设备类进行了更加细致的定义,其值随bDeviceClass字段的不同而有所区别:
当bDeviceClass字段值在01~FEH之间的时候,bDeviceSubClass字段表示标准设备类的子类。例如对于前面的HID设备类,只有一个子类代码01H。而对于显示设备类(04H),子类代码01H表示CRT显示器、02H表示平面显示器、03H表示3D显示器。
当bDeviceClass字段值为0时,bDeviceSubClass字段也必须为0;
当bDeviceClass字段值为FFH时,bDeviceSubClass字段必须由用户自定义设备子类。
6.bDeviceProtocol 字段
bDeviceProtocol字段用于表示USB设备所采用的设备类协议,长度占用1个字节,地址偏移量为6。bDeviceProtocol字段的值和bDeviceClass及bDeviceSubClass的值有关。如果该USB设备属于某个设备类和设备子类,则应该在bDeviceProtocol字段继续指名所采用的设备类协议。当bDeviceProtocol字段为0时,表示不使用任何设备类协议。当bDeviceProtocol字段为FFH时,表示设备类协议由用户自定义。
7.bMaxPackerSize0字段
bMaxPackerSize0字段用于表示在USB设备中,端点0所支持最大数据包的长度,长度占用1个字节,地址偏移量为7。bMaxPackerSize0字段以字节为单位,对于不同速率的设备而不同:对于低速USB设备,bMaxPackerSize0=8。对于全速USB设备,bMaxPackerSize0=8、16、32或64。对于高速USB设备,bMaxPackerSize0=64。对于超速USB设备,bMaxPackerSize0=512。
8.idVendor字段
idVendor字段用于表示USB设备的供应商ID,长度占用2个字节,地址偏移量为8。USB-IF组织中规定,每种USB设备都必须包含一个供应商ID,这样可以使主机为其寻找和加载合适的驱动程序。
9.idProduct字段
idProduct字段用于表示USB设备的产品ID,长度占用2个字节,地址偏移量为10。idProduct字段由设备供应商提供,用于表示某个供应商的特定USB设备。在USB设备上电的时候,该字段可以帮助USB主机选择合适的驱动程序。
10.bcdDevice字段
bcdDevice字段用于表示USB设备的版本号,长度占用2个字节,地址偏移量为12。bcdDevice字段以BCD码的形式表示,一般来说该字段由设备供应商指定。在USB设备上电的时候,该字段可以帮助USB主机选择合适的驱动程序。
11.iManufacturer字段
iManufacturer字段用于表示供应商字符串描述符的索引值,长度占用1个字节,地址偏移量为14。iManufacturer字段所指向的具体字符串内容在后面字符串描述符中定义。iManufacturer字段为0,表示没有供应商字符串。
12.iProduct字段
iProduct字段用于表示产品字符串描述符的索引值,长度占用1个字节,地址偏移量为15。iProduct字段所指向的具体字符串内容在后面字符串描述符中定义。iProduct字段为0,表示没有产品字符串。
13.iSerialNumber字段
iSerialNumber字段用于表示设备序列号字符串描述符的索引值,长度占用1个字节,址偏移量为16。iSerialNumber字段所指向的具体字符串内容在后面字符串描述符中定义。iSerialNumber字段为0,表示没有设备序列号字符串。
14.bNumConfigurations字段
bNumConfigurations字段用于表示该USB设备所支持的配置数,长度占用1个字节,地址偏移量为17。如果USB设备仅有一个配置,则bNumConfigurations=1,具有多个配置时该值可以大于1。
三、配置描述符(Configuration)
在USB总线接口协议中,USB配置描述符描述了USB设备的配置信息,包括接口数量、功耗等信息。每个USB设备都必须有一个配置描述符。另外,一个USB设备还可以有多个配置,但是每次传输过程仅使用其中的一个配置信息来完成。
1、配置描述符定义
USB配置描述符由8个字段按照固定的顺序组成,该描述符的总长度固定为9个字节。USB配置描述符各个字段的格式,如表7.3所示。
下面详细说明USB配置描述符各个字段的具体含义:
1.bLength字段
bLength字段用于表示USB配置描述符的长度,长度占用1个字节,地址偏移量为0。对于USB配置描述符来说,bLength字段的值固定为9,也就是09H。
2.bDescriptorType字段
bDescriptorType字段用于表示USB描述符的类型值,长度占用1个字节,地址偏移量为1。对于USB配置描述符来说,bDescriptorType字段的值固定为02H。
3.wTotalLength字段
wTotalLength字段用于表示配置信息的总长度,长度占用2个字节,地址偏移量为2。wTotalLength字段所设置的数值必须包括配置描述符、接口描述符和端点描述符长度的总和。
4.bNumInterfaces字段
bNumInterfaces字段用于表示配置所支持的接口数,长度占用1个字节,地址偏移量为4。一般来说,USB设备的接口数大于等于1,因此其最小值为1。
5.bConfigurationValue字段
bConfigurationValue字段用于表示USB设备的配置值,长度占用1个字节,地址偏移量为5。
6.iConfiguration字段
iConfiguration字段用于指出配置字符串描述符的索引值,长度占用1个字节,地址偏移量为6。iConfiguration字段所包含的具体字符串内容在后面字符串描述符中定义。如果没有配置字符串,iConfiguration字段可以置为0。
7.bmAttributes字段
bmAttributes字段用于表示USB设备的配置特性,长度占用1个字节,地址偏移量为7。bmAttributes字段是按位寻址的,各个位的含义如下:
D0~D4:保留值,一般置为0。
D5:设置为1表示支持远程唤醒功能,否则不支持。
D6:设置为1表示自供电,否则不支持。
D7:设置为1表示总线供电,否则不支持。
8.bMaxPower字段
bMaxPower字段用于表示USB设备运行时,所需要消耗的总线电流,长度占用1个字节,地址偏移量为8。bMaxPower字段所设置数值的单位以2mA为基准。需要注意的是,不同的版本支持的最大电流不同,bMaxPower字段可以设置的值也不同。
高速USB2.0设备可以从USB总线上获得最大的电流为500mA,因此bMaxPower字段的最大值可以设置为250。
超速USB3.0设备可以从USB总线上获得最大的电流为900mA,因此bMaxPower字段的最大值可以设置为450。
四、字符串描述符(String)
USB字符串描述符用于保存一些供应商名称、产品序列号等文本信息。在USB总线接口协议中,USB字符串描述符并不是必须的,设计者可以根据需要设置、增加或者减少。
1、字符串描述符定义
USB字符串描述符由3个字段按照固定的顺序组成,该描述符的总长度不是固定的,其长度随字符串的数量和信息的长度而变化。USB字符串描述符各个字段的格式,如表7.4所示。
下面详细说明USB字符串描述符各个字段的具体含义:
1.bLength字段
bLength字段用于表示USB字符串描述符的长度,长度占用1个字节,地址偏移量为0。对于USB字符串描述符来说,bLength字段的值不固定。如果所列字符串的长度为N,那么bLength字符需要设置为N+2。
2.bDescriptorType字段
bDescriptorType字段用于表示USB字符串描述符的类型值,长度占用1个字节,地址偏移量为1。对于USB字符串描述符来说,bDescriptorType字段的值固定为03H。
3.bString字段
bString字段是存储的字符串,长度不固定,地址偏移量为2。bString字段采用UNICODE编码来存储各个字符。
注意:USB字符串描述符可以包含多个。
五、接口描述符(Interface)
USB接口描述符是每个USB设备所必需包含的,接口描述符用来表示在USB设备中各个接口的特性,包括接口的端点个数、所属的设备类和子类等。在USB总线接口协议中,所谓“接口”就是一个USB端点的集合。通过USB接口,可以完成USB设备的特定功能,例如数据输入、输出等等。
1、接口描述符定义
USB接口描述符由9个字段按照固定的顺序组成,该描述符的总长度固定为9个字节。USB接口描述符各个字段的格式,如表7.5所示。
下面详细说明USB接口描述符各个字段的具体含义:
1.bLength字段
bLength字段用于表示USB接口描述符的长度,长度占用1个字节,地址偏移量为0。对于USB接口描述符来说,bLength字段的值固定为9,也就是09H。
2.bDescriptorType字段
bDescriptorType字段用于表示USB描述符的类型值,长度占用1个字节,地址偏移量为1。对于USB接口描述符来说,bDescriptorType字段的值固定为04H。
3.bInterfaceNumber字段
bInterfaceNumber字段用于表示接口的接口号,长度占用1个字节,地址偏移量为2。
4.bAlterateSetting字段
bAlterateSetting字段用于表示接口的可替换设置值,长度占用1个字节,地址偏移量为3。
5.bNumEndpoints字段
bNumEndpoints字段用于表示接口所使用的端口数,长度占用1个字节,地址偏移量为4。这里需要注意,bNumEndpoints字段所设置的数值是除端点0以外的所有端点总数。
6.bInterfaceClass字段
bInterfaceClass字段用于表示接口所属的设备类,长度占用1个字节,地址偏移量为5。bInterfaceClass字段的取值含义如下:
当bInterfaceClass字段为01~FEH时,表示该接口属于USB定义的某个设备类。
当bInterfaceClass字段为FFH时,表示该设备类是供应商自定义的。
7.bInterfaceSubClass字段
bInterfaceSubClass字段用于表示接口所属的USB设备子类,长度占用1个字节,地址偏移量为6。bInterfaceSubClass字段的值与bInterfaceClass字段的值相关。
当bInterfaceClass字段为0时,bInterfaceSubClass字段必须为0。
如果bInterfaceClass字段为01~FEH之间,bInterfaceSubClass字段需进一步表示设备子类。
如果bInterfaceClass字段为FFH时,则需要由供应商自定义设备子类。
8.bInterfaceProtocol字段
bInterfaceProtocol字段用于表示接口所采用的USB设备类协议,长度占用1个字节,地址偏移量为7。bInterfaceProtocol字段的值和bInterfaceClass及bInterfaceSubClass的值有关。
当bInterfaceProtocol字段为0时,表示不使用任何设备类协议。
当bInterfaceProtocol字段为01~FEH时,表示该USB设备属于某个设备类和设备子类,则应该继续指名所采用的设备类协议。
当bInterfaceProtocol字段为FFH时,则需要由供应商自定义设备类协议。
9.iInterface字段
iInterface字段用于指出接口字符串描述符的索引值,长度占用1个字节,地址偏移量为8。iInterface字段所设置具体字符串的内容在后面字符串描述符中定义。如果没有接口字符串,可以置为0。
六、端点描述符(Endpoint)
USB端点描述符是每个USB设备所必需包含的,USB端点是USB数据传输的通道。USB端点描述符表示了USB设备端点的特性,包括其所支持的传输类型、传输方向等信息。在USB总线接口协议中规定,端点0没有端点描述符,其余每一个端点都必须包含一个端点描述符。
1、端点描述符定义
USB端点描述符由6个字段按照固定的顺序组成,该描述符的总长度固定为7个字节。USB端点描述符各个字段的格式,如表7.6所示。
1.bLength字段
bLength字段用于表示USB端点描述符的长度,长度占用1个字节,地址偏移量为0。对于USB端点描述符来说,bLength字段的值固定为7,也就是07H。
2.bDescriptorType字段
bDescriptorType字段用于表示USB描述符的类型值,长度占用1个字节,地址偏移量为1。对于USB端点描述符来说,bDescriptorType字段的值固定为05H。
3.bEndpointAddress字段
bEndpointAddress字段用于表示端点的端点号以及端点的数据传输方向,长度占用1个字节,地址偏移量为2。bEndpointAddress字段采用按位寻址的方式,各位的含义如下:
D7位表示端点的数据传输方向,0表示OUT数据传输,1表示IN数据传输。
D3~D0位表示端点号,例如001B表示端点1、010B表示端点2等。
其余位均保留,必须置0。
4.bmAttributes字段
bmAttributes字段用于表示端点的特性,长度占用1个字节,地址偏移量为3。bmAttributes字段采用按位寻址的方式,各位的含义如下:
D1~D0位表示端点的数据传输类型,00B表示控制传输、01B表示同步传输、10B表示块传输、11B表示中断传输。
D3~D2位进一步描述了不同的传输类型,例如如果是同步传输,这两位表示同步类型,00B表示非同步、01B表示异步、10B表示自适应、11B表示同步。
D5~D4位表示端点的用法类型,00B表示数据端点、01B表示显示反馈端点、10B表示隐式反馈端点、11B保留。
其余位保留。
5.wMaxPacketSize字段
wMaxPacketSize字段用于表示端点所支持最大数据包的长度,长度占用2个字节,地址偏移量为4。wMaxPacketSize字段采用按位寻址的方式,各位的含义如下:
D10~D0位表示数据包长度。
D12~D11位指出每小帧最多传输的事务处理数。
其余位均保留,必须设置0。
6.bInterval字段
bInterval字段用于指定端点数据传输的访问间隔,长度占用1个字节,地址偏移量为6。对于不同的端点类型,bInterval字段的取值可以参阅USB相关协议。例如:
对于低速中断端点,取值范围为10~255,对应的访问间隔为10ms~255ms。
对于全速中断端点,取值范围为1~255,对应的访问间隔为1ms~255ms。
七、USB设备请求概述
在USB总线接口协议中,使用USB设备请求来对USB描述符进行读取和写操作,这样USB主机才可以获取该设备的产品信息和能力。
1、标准USB设备请求概述
USB协议中规定了一些标准USB设备请求,如表7.9所示。标准USB请求对每个USB设备都是必需的。除了这些标准设备请求,USB协议中还允许使用自定义的请求来完成更多的操作。
其中,USB请求号02H、04H是未定义的,用于将来其他用途保留的。在USB总线接口协议中,所有的USB设备必须支持这些标准的USB请求,这就要求设备能够响应标准USB设备请求。如果USB设备对某个请求不需要进行操作,则可以通过返还一个空响应来表示。
2、USB设备请求处理过程
USB设备通过端点0的控制请求通道来响应USB设备请求。当USB功能设备连接到USB主机上的时候,USB主机首先通过标准的USB设备请求与USB功能设备进行通信。需要强调的是,USB设备请起均通过USB控制传输来完成,使用控制管道和USB功能设备进行通信。由前面的介绍可知,控制传输包括建立阶段、数据阶段和状态阶段三个环节,数据过程如下:
(1)在建立阶段,USB主机采用SETUP事务向USB设备发送控制请求。
(2)然后在数据阶段,USB主机或者USB设备响应控制请求并返回指定数据。
(3)最后,USB设备向主机报告控制事务建立阶段和数据阶段的传输结果。对于一个USB设备请求来说,最重要的是建立阶段的SETUP事务的控制请求和数据阶段的数据。对于每一个标准设备请求来说,SETUP事务都按照顺序包括6个字段,各个字段的含义如下:
bmRequestType字段:请求类型,长度占用1个字节。bmRequestType字段采用按位寻址的方式,D7=0表示主机到设备的请求,D7=1表示设备到主机的请求;D6~D5表示了设备请求类型,0表示标准设备请求,1表示USB类设备请求,2表示供应商设备请求,3为保留值;D4~D0表示了请求的接收者,0表示USB设备,1表示接口,2表示端点,3表示其他,其余的均为保留值。bRequest字段:标准设备请求号,长度占用1个字节。
wValue字段:不同的请求具有不同的含义,长度占用2个字节。
wIndex字段:不同的请求具有不同的含义,长度占用2个字节。
wLength字段:不同的请求具有不同的长度,长度占用2个字节。在数据阶段,根据不同的请求类型和设备请求号来决定数据内容及格式,并按照wLength字段所设置的数值来传输指定大小的数据。
USB主机读取描述符后,便可以从中获得该USB功能设备的产品信息和功能配置。下面将主要介绍这些典型的USB标准设备请求。