USB 控制传输方式
控制传输是一种特殊的传输方式。当USB设备初次连接主机时,用控制传输传送控制命令等对设备进行配置。同时设备接入主机时,需要通过控制传输去获取USB设备的描述符以及对设备进行识别,在设备的枚举过程中都是使用控制传输进行数据交换。
控制传输的特点
控制传输相对于其它三个传输方式比较复杂,且具有以下特点:
- 无论低速设备还是高速设备都可以使用控制通道。
- 高速模式的最大包长固定为64个字节;
全速模式可在8、16、32、64字节中选择;
低速模式的最大包长固定为8个字节。 - 超高速USB3.0控制端点有固定的最大控制传输的数据有效载荷为 512 字节,最大突发大小为 1.
- 控制传输的应用场合:主要应用于设备的枚举过程(如读取设备描述符,设置地址,设置配置等)和对数据准确性要求较高的场合。
控制传输最大包长度
控制传输的过程
控制传输分为三个过程:
- 建立过程
- 数据过程(可选)
- 状态过程。
建立过程:
a. 主机发送令牌包:SETUP
b. 主机发送数据包:DATA0
c. 设备返回握手包:ACK或不应答
注意:设备不能返回NAK或STALL,即设备必须接收建立事务的数据。建立过程是建立事务,建立事务是通过SETUP令牌包,其次是DATA0数据包,最后是握手包,设备只能使用ACK来应答(或者由于出错不应答),而不能使用NAK或者STALL来应答,即设备必须接收建立事务的数据。
数据过程(可选):
一个数据过程可以不包括或包含多个数据事务,但所有数据事务必须是同一方向的,即在控制读传输中,数据过程中的数据事务都必须是输入的,在控制写传输过程中,数据过程中的事务都必须是输出。若数据方向发生了改变,则认为进入状态过程。数据过程的第一个数据包必须为DATA1,然后每次正确传输一个数据包后就在DATA0和DATA1之间交替。
状态过程:
状态过程只使用DATA1包,并且传输方向与数据过程相反,即控制写输出在状态过程中使用一个批量输入事务,控制读输入在状态过程中使用一个批量输出事务。
状态过程是要返回数据传输的成功与否,具体也需要看控制传输的类型。需要注意的是,状态信息的数据传输方向与数据阶段方向相反。其实我们来思考下,主机给设备把一推数据发送完毕了(OUT事务),主机肯定要请求一个IN事务,让设备把自己的接收情况发给主机,你设备要给我说你在本轮接收数据有没有问题,同样的,设备把数据发送给主机(IN事务),主机肯定要发起一个OUT事务请求,告诉设备主机的接收情况,告诉设备本轮接收数据有没有问题。
控制传输示例图
USB控制读
在控制读传输状态阶段时时,该阶段则为OUT事务,其中的数据包固定为DATA1数据包。返回数据成功与否以有以下情况:
1)、读数据成功 主机发送OUT令牌包(ping令牌包,高速情况下),主机发送0长度数据包,设备ACK。
2)、数据传输出错 主机发送OUT令牌包(ping令牌包,高速情况下),主机发送0长度数据包,设备STALL。
3)、设备忙(比如正在写数据) 主机发送OUT令牌包(ping令牌包,高速情况下),主机发送0长度数据包,设备NAK
USB控制写
在控制读传输状态阶段时,该阶段则为IN事务,其中的数据包固定为DATA1数据包。返回数据成功与否以有以下情况:
1)、写数据成功,主机发送IN令牌包,设备发送0长度数据包,主机回复ACK。
2)、数据传输出错, 主机发送IN令牌包,设备回复STALL。
3)、设备忙(比如正在写数据),主机发送IN令牌包,设备回复NAK。
USB2.0 控制传输数据包PID序列参考:https://www.usbzh.com/article/detail-708.html
USB无数据控制写
该阶段则为IN事务,其规则与控制写传输相似。
USB控制传输抓包分析
读数据-USB控制传输抓包分析
控制读传输在初始设置阶段会发起一个SETUP事务,从这个SETUP事务我们可以知道是设备给主机传输数据,并且数据长度是255,具体的协议后期会详解,大家在这里把先控制传输理解到位,接着在数据阶段完成数据交换(因为是设备给主机传输数据,所以是数据阶段是IN事务),最后在状态信息阶段主机给设备发送一个OUT事务表明自己接收是否异常。
写数据-USB控制传输抓包分析
控制写传输在初始设置阶段同样会发起一个SETUP事务,从这个SETUP事务我们可以知道是主机向设备传输数据,并且数据长度是12,接着在数据阶段完成数据交换(因为是主机给设备传输数据,所以数据阶段是OUT事务),最后在状态信息阶段主机发起一个IN事务,请求设备回答接收情况。
无数据-USB控制传输抓包分析
无数据控制传输在初始设置阶段同样会发起一个SETUP事务,从这个SETUP事务看到数据长度是0,因此无数据阶段,最后在状态信息阶段主机发起一个IN事务,请求设备回答接收情况。
本文部分内容来自我的好友的CSDN博客:https://hellocode.blog.csdn.net/article/details/112573949