1.前言
USB设备状态切换图
2.传输细节
2.1 传输(Transfer)和事务(Transaction)
想输出数据,可以发出OUT令牌包,OUT令牌包可以指定目的地。但是数据如何传输呢?还需要发出DATA0或DATA1数据包。设备收到数据后,还要回复一个ACK握手包。
所以,完整的数据传输,需要涉及多个包:令牌包、数据包、握手包。这个完整的数据传输过程,被称为事务(Transaction)。
有些事务需要握手包,有些事务不需要握手包,有些事务可以传输很大的数据,有些事务只能传输小量数据。
握手包存在的意义就是上一篇所讲的,数据包特么会丢失呀!
有四类事务:
- 批量事务:用来传输大量的数据,数据的正确性有保证,时效没有保证。
- 中断事务:用来传输周期性的、小量的数据,数据的正确性和时效都有保证。
- 实时事务:用来传输实时数据,数据的正确性没有保证,时效有保证。
- 建立事务:跟批量事务类似,只不过令牌包是SETUP令牌包。
有四类传输(Transfer):
- 批量传输:就是使用批量事务实现数据传输,比如U盘。
- 中断传输:就是使用中断事务实现数据传输,比如鼠标。
- 实时传输:就是使用实时事务实现数据传输,比如摄像头。
- 控制传输:由建立事务、批量事务组成,所有的USB设备都必须支持控制传输,用于"识别/枚举"
过程(stage)和阶段(phase)的概念
事务由多个包组成,比如Host要发送数据给设备,这就会涉及很多个包:
Host发出OUT令牌包,表示要发数据给哪个设备
Host发出DATA0数据包
设备收到数据后,回应ACK包
这个完整的事务涉及3个包(Packet),分为3个阶段(Phase):
- 令牌阶段(Token phase):由令牌包实现
- 数据阶段(Data phase):由数据包实现
- 握手阶段(Handshake phase):由握手包实现
事务由包组成,这些包分别处于3个阶段(phase):令牌阶段,数据阶段,握手阶段。
对于批量传输、中断传输、实时传输,它们分别由一个事务组成,不再细分为若干个过程。但是控制传输由多个事务组成,这些事务分别处于3个过程:建立过程(stage)、数据过程(stage)、状态过程(stage)。
总结起来就是:
- 控制传输由多个过程(stage)组成,每个过程由一个事务来实现。
- 每个事务由多个阶段(phase)组成,每个阶段由一个包来实现。
2.2 批量传输
批量传输用批量事务来实现,用于传输大量的数据,数据的正确性有保证,时效没有保证。
批量事务由3个阶段(phase)组成:令牌阶段、数据阶段、握手阶段。每个阶段都是一个完整的包,含有SOP、SYNC、PID、EOP。
下图中各个矩形框就对应一个完整的包。
《圈圈教你玩USB》中有详细的示例:
2.3 中断传输
中断传输用中断事务来实现,用于传输小量的、周期性的数据,数据的正确性和时效都有保证。
中断事务由3个阶段(phase)组成:令牌阶段、数据阶段、握手阶段。每个阶段都是一个完整的包,含有SOP、SYNC、PID、EOP。
中断端点在端点描述符中要报告主机对此端点的查询时间,主机会保证在小于这个时间间隔的范围内安排一次传输,比如HOST主机1ms内向鼠标设备请求一次数据。对于全速端点,中断传输的时间间隔在1ms到255ms之间,对于低速端点,时间间隔限制在10ms到255ma之间,对于高速端点,时间间隔为2^(bInterval-1) x 125us,bInterval的值在1-16之间。
下图中各个矩形框就对应一个完整的包。
中断事务跟批量事务非常类似,Host使用它来周期性地读数据、写数据。
以鼠标为例,我们需要及时获得鼠标的数据,不及时的话你会感觉鼠标很迟钝。但是USB协议中并没有中断功能,它使用"周期性的读、写"来实现及时性。具体过程如下:
- Host每隔n毫秒发出一个IN令牌包
- 鼠标有数据的话,发出DATA0或DATA1数据包给Host;鼠标没有数据的话,发出NAK给Host。
中断事务的优先级比批量事务更高,它要求实时性,而批量事务不要求实时性。
2.4 实时传输
实时传输用实时事务来实现,用于传输实时数据,对数据的正确性没有要求。
实时事务由2个阶段(phase)组成:令牌阶段、数据阶段。每个阶段都是一个完整的包,含有SOP、SYNC、PID、EOP。
实时事务不需要握手阶段,一个示例的场景是:为了传输摄像头的实时数据,偶尔的数据错误是可以忍受的,大不了出现短暂的花屏。如果为了解决花屏而重传数据,那就会导致后续画面被推迟,实时性无法得到保证。
因此实时事务也就没有应答包。数据是否正确,可以由数据包的 CRC 校验来确认,至于出错的数据如何处理,由软件决定。也就是接收方是可以通过CRC知道数据正确与否的。
下图中各个矩形框就对应一个完整的包。
实时事务跟中断事务非常类似,Host也会周期性的发起实时事务,主要区别在于:
- 实时事务不要求准确性,没有握手阶段
- 实时事务传输的数据量比较大,中断事务传输的数据量比较小
2.5 控制传输
在使用批量传输时,使用IN令牌包或OUT令牌包表示数据传输方向。
控制传输的令牌包永远是SETUP,怎么分辨是读数据,还是写数据?发出SETUP令牌包后,还要发出DATA0数据包,根据数据的内容来确定后续是读数据,还是写数据。这个过程称为"建立事务"(SETUP Transaction)
但是控制传输由多个事务组成,这些事务分别处于3个过程:建立过程(stage)、数据过程(stage)、状态过程(stage)。
- 建立过程(stage),使用SETUP事务:Host发出SETUP令牌包、DATA0数据包、得到ACK握手包
- 数据过程(stage),使用批量事务:
- 对于输出:Host发出OUT令牌包,发出DATA0、DATA1数据包、得到ACK握手包
- 对于输入:Host发出IN令牌包,读到DATA0、DATA1数据包、发出ACK握手包
- 状态过程(stage),使用批量事务:
- 对于输出:Host发出IN令牌包,读到DATA1数据包,发出ACK握手包
- 对于输入:Host发出OUT令牌包,发出DATA1数据包,等待ACK握手包
上图中的每一个方框,都是一个完整的事务,含有:Token Packet、Data Packet、Handshake Packet。
3. 使用工具体验数据格式
LeCroy(力科)成立于1964年,是一家专业生产示波器厂家。旗下生产有数字示波器、SDA系列数字示波器、混合信号示波器、模块化仪器、任意波形发生器。
可以在搜索引擎里搜"usbprotocolsuite"。
安装"usbprotocolsuite"后,可以在文档目录里找打很多示程序(后缀名为usb):
使用"usbprotocolsuite"打开这些文件,即可体验USB数据传输: