Linux usb system(descriptor)
为了更好地描述USB设备的特征,USB提出了设备架构的概念。从这个角度来看,可以认为USB设备是由一些配置、接口和端点组成,即一个USB设备可以含有一个或多个配置,在每个配置中可含有一个或多个接口,在每个接口中可含有若干个端点。
这个步骤一般是在设备接入主机时设备进行枚举时完成的这些单元之间的关系如下:
解释说明:
- USB设备可以看作提供了多个串口的设备,依据USB的规范,我们将每个串口称作端点(Endpoint),要和这个端点通信,我们就要打开到这个端点的连接,这个连接就是管道(Pipe)。
- 由于一个设备可能要适应多种情况,端点的设置会有多套,以备使用。端点设置称为接口(Interface)。USB设备展现给我们能够找到的东西就是这些Interface,我们选择要用的Interface,就可以找到Endpoint,再打开Endpoint,就可以传输数据了。
- 配置和接口是对USB设备功能的抽象,实际的数据传输由端点来完成。在使用USB设备前,必须指明其采用的配置和接口,在驱动程序开始的时候,需要记录下这些Interface,一个接口对应一个驱动。
- 在Linux系统的终端通过输入
lsusb -v
,可以看下详细的描述信息,可以先输入查看下,熟悉下框架。
描述符的分类如下,除了比标准的描述符外,如果标准设备类为HID或Hub,可会有对应的HID描述符或Hub描述符:
- 标准描述符(设备描述符、配置描述符、字符串描述符、接口描述符、端点描述符、设备限定描述符、其他速率配置描述符)
- HID描述符
- Hub描述符
这边将描述符的主要四个描述符(设备描述符、配置描述符、接口描述符、端点描述符)进行说明,这四个是必须的,其他描述符是选配。
1.1 设备描述符
位于/include/linux/usb/ch9.h中,如下:
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
}
各字段含义:
- bLength: 表示描述符的长度,对于设备描述符来说,其值为18,即0x12。
- bDescriptorType: 描述符类型,对应表1中的值,设备描述符为0x01。
- bcdUSB:该设备遵循的USB版本号,以BCD码表示,USB1.1为0x0101,USB2.0为0x0200。
- bDeviceClass:该设备所属的标准设备类,USB协议中对常见的设备进行了分类。该字段值为0x01~0xFE时,表示是USB协议中已定义的设备类,常用的HID设备类编号为0x03,其它设备类编号参考:http://www.usb.org/developers/defined_class
- bDeviceProtocol:用于表示USB设备类所采用的设备类协议,其值和bDeviceClass和
bDeviceSubClass有关。当此字段为0时,表示不使用任何设备类协议。如果该USB设备属于某个设
备类和设备子类,则应该继续指明所采用的设备类协议。当该字段为0xFF时,表明设备类协议由供应商自定义。 - bMaxPacketSize0:用于表示在USB设备中,端点0所支持最大数据包的长度,它以字节为单位。对于低速USB设 备,bMaxPacketSize0为8;对于全速USB设备,bMaxPacketSize0为8、16、32、64;对于高速USB设 备,bMaxPacketSize0为64。
- IdVendor:用于表示USB设备供应商的ID。USB组织中规定每种产品都必须包含一个供应商ID,这样可以使主机加载合适的驱动程序。
- idProduct:用于表示USB产品的ID,由设备供应商提供。idProduct用于表示特定的USB设备,在USB设备上电的时候可以帮助USB主机选择合适的驱动程序。
- bcdDevice:用于表示USB设备的版本号,它以BCD码的形式表示。一般来说bcdDevcie由设备供应商指定,在USB设备上电的时候可以帮助USB主机选择合适的驱动程序。
- iManufacturer:用于表示供应商字符串描述符的索引值。具体字符串的内容在后面字符串描述符中定义。如果没有供应商字符串,可以置0。
- iSerialNumber:用于表示设备序列号字符串描述符的索引值,如果没有,可以置为0。
- bNumConfigurations:用于表示该USB设备所支持的配置数。
1.2 配置描述符
位于/include/linux/usb/ch9.h中,如下:
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
}
各个字段含义:
- bLength:用于表示配置描述符的长度,固定为9个字节,即0x09。
- bDescriptorType:用于表示配置描述符的类型值,固定为0x02。
- wTotalLength:用于表示配置信息的总长度,包括配置描述符、接口描述符、端点描述符长度的总和。
- bNumInterfaces:用于表示配置所支持的接口数。一般来说,USB设备的接口至少有一个,因此其最小值为1。
- bConfigurationValue:用于表示USB设备的配置值。
- iConfiguration:用于指出配置字符串描述符的索引值。具体字符串的内容在后面字符串描述符中定义。如果没有配置字符串,可以置为0。
- bmAttributes:用于表示USB设备特性。bmAttributes是接位寻址的,第6位置1表示使用总线电源;第5位置1表示支持远程唤醒功能;该字段其他位均保留,一般来说,第0~4位置0即可,第7位置1即可。
- bMaxPower:用于表示USB设备运行时所需要消耗的总线电流,单位以2mA为基准。USB设备可以从USB总线上获得最大的电流为500mA,因此bMaxPower字段的最大值可以设置为250。
1.3 接口描述符
位于/include/linux/usb/ch9.h中,如下:
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
}
各字段含义:
- bLength:用于表示接口描述符的长度.固定为9字节,即0x07。
- bDescriptorType: 用于表示接口描述符的类型值.固定为0x04。
- bInterfaceNumber:用于表示该接口的编号。
- bAlternateSetting:用于为上一个字段选择可供替换的位置.即备用的接口描述符标号。
- bNumEndpoints:使用的端点数目.端点0除外。
- bInterfaceClass:类型代码(由USB分配)。
- bInerfaceSubclass:子类型代码(由USB分配)。
- bInterfaceProtocol:协议代码(由USB分配)。
- iInterface:字符串描述符的索引。
1.4 端点描述符
位于/include/linux/usb/ch9.h中,如下:
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
}
各字段含义:
- bLength:用于表示端点描述符的长度,固定为7字节,即0x07。
- bDescriptorType:用于表示接口描述符的类型值,固定为0x05。
- bEndpointAddress:用于表示端点的端点号以及端点的数据传输方向。第七位表示端点的数据传输方向,0表示OUT数据传输,1表示IN数据传输;第0~位表示端点号,例如001B表示端点1、010B表示端点2;其余位均保留,必须置0。
- bmAttributes:用于表示端点的特性。其中第0位和第1位表示端点的数据传输类型,00B表示控制传输、01B表示同步传输、10B表示块传输、11B表示中断传输;如果是同步传输,第2位和第3位表示同步类型,00B表示非同步、01B表示异步、10B表示自适应、11B表示同步;第4、5 位表示端点的用法类型,00B表示数据端点、01B表示显示反馈端点、10B表示隐匿反馈端点、11B保留。其余位保留。
- wMaxPacketSize:用于表示端点所支持最大数据包的长度。其中第0~10位表示数据包的长度,第11位和12位指出每小帧最多传输的事务数,其余位均保留,必须置0。
- bInterval:用于指定端点数据传输的访问间隔。低速中断端点,取值范围为10~255,对应的访问间隔为10~255ms;对于全速中断端点,取值范围为1~255,对应的访问间隔为1~255ms;对于其他端点,可以参阅USB相关协议。
1.5 USB端点分类
USB 通讯的最基本形式是通过端点。一个USB端点只能向一个方向传输数据(从主机到设备(称为输出端点)或者从设备到主机(称为输入端点)),端点可被看作一个单向的管道。
USB 端点有 4 种不同类型, 分别具有不同的数据传送方式:
1.控制CONTROL
控制端点被用来控制对USB设备的不同部分访问.通常用作配置设备、获取设备信息、发送命令到设备或获取设备状态报告。这些端点通常较小。每个USB设备都有一个控制端点称为"端点 0", 被 USB 核心用来在插入时配置设备。USB协议保证总有足够的带宽留给控制端点传送数据到设备。
2.中断INTERRUPT
每当 USB 主机向设备请求数据时,中断端点以固定的速率传送小量的数据。此为USB键盘和鼠标的主要的数据传送方法。它还用以传送数据到USB设备来控制设备。通常不用来传送大量数据。USB协议保证总有足够的带宽留给中断端点传送数据到设备。
3.批量BULK
批量端点用以传送大量数据,这些端点通常比中断端点大得多,它们普遍用于不能有任何数据丢失的情况。USB协议不保证传输在特定时间范围内完成。如果总线上没有足够的空间来发送整个BULK包,它被分为多个包进行传输。这些端点普遍用于打印机、USB Storage和USB网络设备上。
4.等时ISOCHRONOUS
等时端点也批量传送大量数据,但是这个数据不被保证能送达。这些端点用在可以处理数据丢失的设备中,并且更多依赖于保持持续的数据流。如音频和视频设备等等。控制和批量端点用于异步数据传送,而中断和等时端点是周期性的。这意味着这些端点被设置来在固定的时间连续传送数据,USB 核心为它们保留了相应的带宽。
Linux usb system(descriptor)的分析就到这边,有感悟时会持续会更新。
注:以上内容都是本人在学习过程积累的一些心得,难免会有参考到其他文章的一些知识,如有侵权,请及时通知我,我将及时删除或标注内容出处,如有错误之处也请指出,进行探讨学习。文章只是起一个引导作用,详细的数据解析内容还请查看Linux相关教程,感谢您的查阅。