Linux-USB驱动(2)-USB协议分析
USB设备逻辑结构
在USB设备的逻辑组织中,包含设备、配置、接口和端点4个层次。设备通常有一个或多个配置,配置通常有一个或多个接口,接口有零或多个端点。
每个USB设备都可以包含一个或多个配置,不同的配置使设备表现出不同的功能组合,配置由多个接口组成。在USB协议中,接口代表一个基本的功能,一个功能复杂的USB设备可以具有多个接口,而接口是端点的汇集。
比如说一个USB播放器带有音频,视频功能,还有旋钮和按钮。
配置1: 音频(接口)+旋钮(接口)
配置2: 视频(接口)+旋钮(接口)
配置3: 音频(接口)+视频(接口)+按钮(接口)
音频接口,视频接口,按钮接口,旋钮接口均需要一个驱动程序。
配置1: 音频(接口)+旋钮(接口)
配置2: 视频(接口)+旋钮(接口)
配置3: 音频(接口)+视频(接口)+按钮(接口)
音频接口,视频接口,按钮接口,旋钮接口均需要一个驱动程序。
USB设备中的唯一可寻址的部分是设备端点,端点的作用类似于寄存器。每个端点在设备内部有唯一的端点号,这个端点号是在设备设计时给定的。主机和设备的通信最终都作用于设备上的各个端点。每个端点所支持的操作都是单向的,要么只读,要么只写。
USB 描述符
当我们把USB设备(如:USB鼠标)插到我们的PC时,主机能够自动识别出我们的USB设备类型。这是为什么呢?
在每一个USB设备内部,包含了固定格式的数据,通过这些数据,USB主机就可以获取USB设备的类型、生产厂商等信息。这些固定格式的数据,我们就称之为USB描述符。标准的USB设备有5种USB描述符:设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。
设备描述符
一个USB设备只有一个设备描述符,设备描述符长度为18个字节,格式如《USB specification》中的Table-9.8所示。
它包含:
bLength : 描述符长度,固定为0x12。
bDescriptorType : 设备描述符类型,固定为0x01。
bcdUSB : USB 规范发布号。表示了本设备能适用于那种协议,如2.0=0200
bDeviceClass : 类型代码。
bDeviceSubClass : 子类型代码。
bDeviceProtocol : 协议代码。
bDescriptorType : 设备描述符类型,固定为0x01。
bcdUSB : USB 规范发布号。表示了本设备能适用于那种协议,如2.0=0200
bDeviceClass : 类型代码。
bDeviceSubClass : 子类型代码。
bDeviceProtocol : 协议代码。
bMaxPacketSize0 : 端点0最大分组大小。
idVendor : 供应商ID。
idProduct : 产品ID(由厂商分配)。
bcdDevice : 设备出产编码,由厂家自行设置。
iManufacturer : 厂商描述符字符串索引.索引到对应的字符串描述符。
iProduct : :产品描述符字符串索引。
idVendor : 供应商ID。
idProduct : 产品ID(由厂商分配)。
bcdDevice : 设备出产编码,由厂家自行设置。
iManufacturer : 厂商描述符字符串索引.索引到对应的字符串描述符。
iProduct : :产品描述符字符串索引。
iSerialNumber : 设备***字符串索引。
bNumConfigurations : 可能的配置数。
bNumConfigurations : 可能的配置数。
bDeviceClass 和bDeviceSubClass 就来区分这个USB设备到底是鼠标、键盘等等
配置描述符
USB配置描述符长度为8个字节,格式如(《USB specification :Table-9.10》)
bLength : 描述符长度,固定为0x09。
bDescriptorType : 配置描述符类型,固定为0x02。
wTotalLength : 返回整个数据的长度,指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小。
bNumInterfaces : 配置所支持的接口数,指该配置配备的接口数量,也表示该配置下接口描述符数量。
bConfigurationValue : 作为Set Configuration的一个参数选择配置值。
iConfiguration : 用于描述该配置字符串描述符的索引。
bmAttributes : 供电模式选择。Bit4-0保留,D7:总线供电,D6:自供电,D5:远程唤醒.
MaxPower : 总线供电的USB设备的最大消耗电流,以2mA为单位
bDescriptorType : 配置描述符类型,固定为0x02。
wTotalLength : 返回整个数据的长度,指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小。
bNumInterfaces : 配置所支持的接口数,指该配置配备的接口数量,也表示该配置下接口描述符数量。
bConfigurationValue : 作为Set Configuration的一个参数选择配置值。
iConfiguration : 用于描述该配置字符串描述符的索引。
bmAttributes : 供电模式选择。Bit4-0保留,D7:总线供电,D6:自供电,D5:远程唤醒.
MaxPower : 总线供电的USB设备的最大消耗电流,以2mA为单位
接口描述符
USB接口描述符长度为8个字节,见《USB specification》Table-9.12。
bLength : 描述符长度,固定为0x09。
bDescriptorType : 接口描述符类型,固定为0x04。
bInterfaceNumber: 该接口的编号。
bAlternateSetting : 用于为上一个字段选择可供替换的设置。
bNumEndpoint : 使用的端点数目,端点0除外。
bInterfaceClass : 类型代码(由USB组织分配)。
bInterfaceSunClass : 子类型代码(由USB组织分配)。
bInterfaceProtocol : 协议代码(由USB组织分配)。
iInterface : 字符串描述符的索引。
bDescriptorType : 接口描述符类型,固定为0x04。
bInterfaceNumber: 该接口的编号。
bAlternateSetting : 用于为上一个字段选择可供替换的设置。
bNumEndpoint : 使用的端点数目,端点0除外。
bInterfaceClass : 类型代码(由USB组织分配)。
bInterfaceSunClass : 子类型代码(由USB组织分配)。
bInterfaceProtocol : 协议代码(由USB组织分配)。
iInterface : 字符串描述符的索引。
端点描述符
USB端点描述符长度为7个字节,格式如(USB specification :Table-9.13)
bLength : 描述符大小,固定为0x07。
bDescriptorType : 接口描述符类型,固定为0x05。
bEndpointType : USB设备的端点地址。Bit7,方向,对于控制端点可以忽略,1/0:IN/OUT。Bit6-4,保留。BIt3-0:端点号.
bmAttributes : 端点属性,Bit7-2,保留。BIt1-0:00控制,01 同步,02批量,03中断。
wMaxPacketSize : 本端点接收或发送的最大信息包大小。
bInterval : 轮训数据传送端点的时间间隔.对于批量传送和控制传送的端点忽略.对于同步传送的端点,必须为1,对于中断传送的端点,范围为1-255。
bDescriptorType : 接口描述符类型,固定为0x05。
bEndpointType : USB设备的端点地址。Bit7,方向,对于控制端点可以忽略,1/0:IN/OUT。Bit6-4,保留。BIt3-0:端点号.
bmAttributes : 端点属性,Bit7-2,保留。BIt1-0:00控制,01 同步,02批量,03中断。
wMaxPacketSize : 本端点接收或发送的最大信息包大小。
bInterval : 轮训数据传送端点的时间间隔.对于批量传送和控制传送的端点忽略.对于同步传送的端点,必须为1,对于中断传送的端点,范围为1-255。
USB数据通信
对于USB协议的分析最好能从现有的一个“包”入手,比如说下面这一副图:
根据这幅图我们也可以已大概看出这个“包”的层次关系。
一个USB的包称为一个传输,
一个传输下分为好几个事务,比如说图中的事务0,1,2,3,4
一个事务又分为好几个包,比如说Packet136、137、138等等。
一个包又分为好几个域或者说字段。
传输
USB的数据通讯首先是基于传输(Transfer)的,传输的类型有:中断传输、批量传输、同步传输、控制传输.
中断传输用于一些小数据量的、实时的传输,比如说鼠标、键盘。
批量传输用于大数据量的传输,比如说U盘,硬盘等等。
同步传输是不可靠传输,它容忍一定的错误,比如所麦克风,喇叭等。
控制传输用于对设备的控制。
根据传输的第一个字节就可以判断出这个传输是属于哪个传输。比如上面这幅图是控制传输
事务
一次传输由一个或多个事务(transaction)构成,事务可分为:In(输入)事务,Out(输出)事务,Setup(设置)事务。同样由第一个字节来区分出是属于哪个事务。上面的包依次是Setup、IN、IN、IN、OUT
包
一个事务由一个或多个包(packet)构成,包可分为:令牌包(setup)、数据包(data)、握手包(ACK)和特殊包。由包的第二个字节来区分是属于哪种包。比如说事务0由3个包构成,Setu、DATA、ACK。
域
一个包由多个域构成,域可分为:同步域(SYNC),标识域(PID),地址域(ADDR),端点域(ENDP),帧号域(FRAM),数据域(DATA),校验域(CRC)。
USB设备枚举
USB设备在正常工作以前, 第一件要做的事就是枚举。枚举是让主机认得这个USB设备, 并且为该设备准备资源,建立好主机和设备之间的数据传递通道。
设备枚举包括以下几个过程:
1. 获取设备描述符
2. 复位
3. 设置地址
4. 再次获取设备描述符(需要查看地址有没有设置成功)
5. 获取配置描述符
6. 获取接口、端点描述符
7. 获取字符串描述符
8. 选择设备配置
2. 复位
3. 设置地址
4. 再次获取设备描述符(需要查看地址有没有设置成功)
5. 获取配置描述符
6. 获取接口、端点描述符
7. 获取字符串描述符
8. 选择设备配置
怎么分析出这些个过程的呢?还是分析上面这幅图。
首先这是一个控制传输,他需要获取一个描述符,具体到设备描述符。
它的事务0的功能就是请求设备描述符。它由3个包构成,包后面的箭头代表数据的流向,分别是流向设备、流向设备、流向主机。
接下来的3个事务都是IN事务,他们就是负责接收设备描述符的,可以发现,3个事务的Data传输量就是18个字节。