USB总线上传输数据是以包(packet)为基本单位的,必须把不同的包组织成事务(transaction)才能传输数据。
USB协议规定了四种传输(transfer)类型:批量传输、同步传输、中断传输和控制传输。其中,批量传输、同步传输和中断传输每传输一次数据都是一个事务,控制传输包括三个过程,建立过程和状态过程分别是一个事务,数据过程则可能包含多个事务。
4.1 包packet
一个包被分为不同域,根据不同类型的包,所包含的域是不一样的。但都要以同步域SYNC开始,紧跟一个包标识符PID,最终以包结束符EOP来结束这个包。
packet
PID域
PID是用来标识一个包的类型的。它共有8位,只使用4位(PID0PID3),另外4位是PID0PID3的取反,用来校验PID
PID
?PID规定了四类包:令牌包、数据包、握手包和特殊包。同类的包又各分为具体的四种包
仅在帧首传输一次SOF包。 (下面有介绍,令牌包)地址域
地址共占11位,其中低7位是设备地址,高4位是端点地址。
地址
帧号域
帧号占11位,主机每发出一个帧,帧号都会自加1,当帧号达到0x7FF时,将归零重新开始计数。
数据域
根据传输类型的不同,数据域的数据长度从0到1024字节不等。
CRC域
校验和
4.1.1 令牌包
令牌包有四种:
1-OUT: 通知设备将要输出一个数据包
2-IN: 通知设备返回一个数据包
3-SETUP: 只用在控制传输中,也是通知设备将要输出一个数据包,与OUT令牌的区别是:只使用DATA0数据包,且只能发到device的控制端点
4-SOF: 在每帧开始时以广播的形式发送,针对USB全速设备,主机每1ms产生一个帧,USB主机会对当前帧号进行统计,每次帧开始时通过SOF包发送帧号。
OUT/IN/SETUP令牌包没有帧号域和数据域。
SOF令牌包没有地址域和数据域。
4.1.2 数据包
数据包没有地址域和帧号域。根据transfer的类型不同,数据包最大长度有所不同。
4.1.3 握手包
握手包有四种可选:
ACK: 传输正确完成
NAK: 设备暂时没有准备好接收数据,或没有准备好发送数据
STALL: 设备不能用于传输
NYET/ERR: 仅用于高速传输,设备没有准备好或出错
握手包仅有PID域。
4.2--事务:
分别有IN、OUT和SETUP三大事务,每一种事务都由令牌包、数据包、握手包三个阶段构成,这里用阶段的意思是因为这些包的发送是有一定的时间先后顺序的,事务的三个阶段如下:
1-令牌包阶段:启动一个输入、输出或设置的事务。
2-数据包阶段:按输入、输出发送相应的数据。
3-握手包阶段:返回数据接收情况,在同步传输的IN和OUT事务中没有这个阶段,这是比较特殊的。
事务的三种类型如下(以下按三个阶段来说明一个事务):
4.2.1、 IN事务:
令牌包阶段——主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;
数据包阶段——设备根据情况会作出三种反应(要注意:数据包阶段也不总是传送数据的,根据传输情况还会提前进入握手包阶段)。
握手包阶段——主机正确接收到数据之后就会向设备发送ACK包。
4.2.2、 OUT事务:
令牌包阶段——主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;
数据包阶段——比较简单,就是主机会往设备送数据,DATA0与DATA1交替
握手包阶段——设备根据情况会作出三种反应
4.2.3、SETUT事务:
令牌包阶段——主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;
数据包阶段——比较简单,就是主机往设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令
//下面字节中含有的bit 位不同,命令也不同
{标准的USB设备请求命令是用在控制传输中的“初始设置步骤”里的数据包阶段(即DATA0,由八个字节构成)。命令共有11个,大小都是8个字节,具有相同的结构,由5个字段构成(字段是标准请求命令的数据部分),结构如下(括号中的数字表示字节数,首字母bm,b,w分别表示位图、字节,双字节):
bmRequestType(1) + bRequest(1) + wvalue(2) + wIndex(2) + wLength(2)
}
握手包阶段——设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后通常是一个IN或OUT事务构成的传输)。
4.3 USB的四种传输类型:
4.3.1. 控制传输:
控制传输是一种可靠的双向传输,一次控制传输可分为三个阶段。第一阶段
为从HOST到Device的SETUP
事务传输,这个阶段指定了此次控制传输的请求类型;
控制传输
第二阶段为数据阶段
,数据过程是可选的。一个数据过程包含一笔或者多笔数据事务。数据过程的第一个数据包必须是DATA1包,然后每次正确传输一个数据包就在DATA0和DATA1之间交替。第三阶段为状态阶段
,状态过程也是一笔批量事务。状态过程只使用DATA1包。
设备枚举过程中各种描述符的获取以及设置地址和设置配置等,都是通过控制传输来实现的。
控制传输通过控制管道在应用软件和 Device 的控制端点之间进行,控制传输过程中传输的数据是有格式定义的,USB 设备或主机可根据格式定义解析获得的数据含义。
其他三种传输类型都没有格式定义。
控制传输对于最大包长度有固定的要求。对于高速设备该值为 64Byte;对于低速设备该值为 8;全速设备可以是 8或 16或 32或 64。
最大包长度 表征了一个端点单次接收/发送数据的能力,实际上反应的是该端点对应的Buffer 的大小。Buffer 越大,单次可接收/发送的数据包越大,反之亦反。
当通过一个端点进行数据传输时, 若数据的大小超过该端点的最大包长度时,需要将数据分成若干个数据包传输,并且要求除最后一个包外,所有的包长度均等于该最大包长度。
这也就是说如果一个端点收到/发送了一个长度小于最大包长度的包,即意味着数据传输结束。
控制传输在访问总线时也受到一些限制
如: a. 高速端点的控制传输不能占用超过 20%的微帧,全速和低速的则不能超过 10%。
b. 在一帧内如果有多余的未用时间,并且没有同步和中断传输,可以用来进行控制传输。
4.3.2. 中断传输:
中断传输是一种轮询的传输方式,是一种单向的传输,HOST通过固定的间隔对中断端点进行查询,若有数据传输或可以接收数据则返回数据或发送数据,否则返回NAK,表示尚未准备好。
中断传输的延迟有保证,但并非实时传输,它是一种延迟有限的可靠传输,支持错误重传
对于高速/全速/低速端点,最大包长度分别可以达到1024/64/8 Bytes。
高速中断传输不得占用超过 80%的微帧时间,全速和低速不得超过 90%。
中断端点的轮询间隔由在端点描述符中定义,全速端点的轮询间隔可以是1255mS,低速端点为10255mS,高速端点为(2interval-1)*125uS,其中 interval取 1到 16之间的值。
除高速高带宽中断端点外,一个微帧内仅允许一次中断事务传输,高速高带宽端点最多可以在一个微帧内进行三次中断事务传输,传输高达 3072 字节的数据。
所谓单向传输,并不是说该传输只支持一个方向的传输,而是指在某个端点上该传输仅支持一个方向,或输出,或输入。如果需要在两个方向上进行某种单向传输,需要占用两个端点,
分别配置成不同的方向,可以拥有相同的端点编号。
4.3.3. 批量传输:
批量传输是一种可靠的单向传输,但延迟没有保证,它尽量利用可以利用的带宽来完成传输,适合数据量比较大的传输。
低速 USB 设备不支持批量传输,高速批量端点的最大包长度为 512,全速批量端点的最大包长度可以为 8、16、32、64。
批量传输在访问 USB 总线时,相对其他传输类型具有最低的优先级,USB HOST 总是优先安排其他类型的传输,当总线带宽有富余时才安排批量传输。
高速的批量端点必须支持PING 操作,向主机报告端点的状态,NYET 表示否定应答,没有准备好接收下一个数据包,ACK 表示肯定应答,已经准备好接收下一个数据包。
4.3.4. 同步传输:
同步传输是一种实时的、不可靠的传输,不支持错误重发机制。只有高速和全速端点支持同步传输,高速同步端点的最大包长度为 1024,低速的为 1023。
除高速高带宽同步端点外,一个微帧内仅允许一次同步事务传输,高速高带宽端点最多可以在一个微帧内进行三次同步事务传输,传输高达 3072 字节的数据。
全速同步传输不得占用超过 80%的帧时间,高速同步传输不得占用超过 90%的微帧时间。 同步端点的访问也和中断端点一样,有固定的时间间隔限制。
4.3.5 分离传输:
在主机控制器和 USB HUB 之间还有另外一种传输——分离传输(Split Transaction),它仅在主机控制器和 HUB之间执行,通过分离传输,可以允许全速/低速设备连接到高速主机。
分离传输对于USB 设备来说是透明的、不可见的。顾名思义就是把一次完整的事务传输分成两个事务传输来完成。其出发点是高速传输和全速/低速传输的速度不相等,如果使用一次完整的事务来传输,势必会造成比较长的等待时间,
从而降低了高速 USB 总线的利用率。通过将一次传输分成两此,将令牌(和数据)的传输与响应数据(和握手)的传输分开,这样就可以在中间插入其他高速传输,从而提高总线的利用率。
总结:USB的最小单元是“域”,由“域”构成了“包”,在由“包”构成了“事务”,最后由“事务”构成了“传输”,在应用层面,我们看到的只是传输,所以USB协议栈就需要完成传输以下的所有事情。这对标准的USB协议栈提出了最基本的要求, 优先级:同步传输 > 中断传输>控制传输>批量传输
开发必备:
枚举的过程实际上用到而且只用到了总线的“控制传输(Control Transfer)”。这种传输方式通常用于配置/命令/状态等情形,其中的设置操作setup和状态操作status过程的数据包具有USB协议定义的数据结构,因此,控制传输只能通过消息管道进行。
一个完整的控制传输包括三个过程:
1、建立连接。
2、数据过程(可选) 。
3、状态过程。
建立连接的过程都是由Host发起,它开始于一个Setup令牌包,后面紧跟一个DATA0包。如果是控制输入传输,数据过程则为输入数据,若是控制输出传输,则数据过程是输出数据。
数据过程的可选型是指设置过程需要指定数据长度,如果指定为0,则没有数据过程。状态过程跟在数据过程之后,状态过程恰好和数据过程的数据传输方向相反,因为此阶段主要是用来确认之前两阶段的所有数据都已经正确传输了。
使用USB View 采集到的数据:
Device Descriptor:
bcdUSB: 0x0100
bDeviceClass: 0xDC
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x10 (16)
idVendor: 0x0471
idProduct: 0x0666
bcdDevice: 0x0100
iManufacturer: 0x00
iProduct: 0x00
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Full
Device Address: 0x02
Open Pipes: 4
Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x01
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x82
Transfer Type: Bulk
wMaxPacketSize: 0x0040 (64)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x02
Transfer Type: Bulk
wMaxPacketSize: 0x0040 (64)
bInterval: 0x0A
REF:
https://blog.csdn.net/u010142953/article/details/82627591
https://blog.csdn.net/songze_lee/article/details/77658094
https://www.cnblogs.com/qiyuexin/p/9043987.html#_label2_1
?