USB2.0 控制传输数据包PID序列
USB数据包的PID序列指的不是数据包的PID序列,特指DATA0,DATA1,DATA2和MDATA的PID序列,即USB在数据传输过程中这些数据包的顺序。
USB的数据传输分为四种,分别为控制传输、同步传输、批量传输和中断传输。这四种数据传输方式除过控制传输,其余数据的传输过程都是通过IN事务或者OUT事务实现的,而控制传输的控制请求是通过SETUP事务实现,后续根据是否有数据可分为是否有OUT或IN事务。
控制传输分为三种类型,分别为写入数据,读取数据和无数据阶段的控制传输类型。
控制传输的三个阶段:
- SETUP阶段:使用DATA0数据传输请求
- 数据阶段:使用DATA1和DATA0交替进行数据传输,直到数据传输完成。
- 状态阶段:必须为DATA1.
控制传输写入数据PID序列
控制传输写入数据的PID序列图如下图所示:
写入数据时,USB主机在SETUP事务阶段通过DATA0向设备发送请求命令,然后在后续的OUT事务中使用交替的DATA1和DATA0包进行数据的传输,直到数据传输完成。设备最后在状态阶段必须使用一个长度为0的DATA1的数据包用于状态反馈。
我们通过查看一个UAC设备,其执行SET_CUR用于设置音频采样率的抓包分析:
从图可以看到:
- SETUP事务编号989,请求命令通过DATA0发送给设备
- 数据阶段只有一个事务989,所以使用的是DATA1传递实际的采样率
- 设备收到设置采样率,回复一个编号为1028的IN事务,数据长度为0,此为状态阶段,用于反馈给主机。
控制传输读取数据PID序列
控制传输读取数据的PID序列图所下图所示:
读取数据时,主机在SETU事务阶段通过DATA0向设备发送USB请求命令,USB设备收到请求命令后,在后续的IN事务中使用DATA1和DATA0包进行数据的传输,直到数据传输完成。主机在状态阶段必须使用一个长度为0的DATA1的数据包用于状态反馈。
这里我们通过抓取一个获取配置描述符的数据分析:
- 事务373由主机通过DATA0发起获取配置描述符
- 事务439,500,559,579使用交替的DATA1和DATA0返回设置的配置描述符,可以看到前几个事务的数据包长度为64字节(可以看出端点0的最大包长度为64字节),最后一包为22字节。
- 最后的584事务由USB主机向设设备发送的数据长度为0,使用的数据包ID为DATA1.这是一个状态包,用于反馈给设备。
PING事务的解释
在这里面可以看到有2个PING的事务,用于主机PING设备是否可以接收数据。这里我们可以看到有两次返回ACK的PING,不过我们隐藏了NAK的事务,完整的过程见下图:
可以看到,事务581,主机PING设备,设备返回ACK。主机认为设备可以收数据,然后使用事务582发送数据,设备说自己当前又接收不了数据。主机又使用事务583PING设备,设备又返回ACK,这时主机又发送OUT事务,这时设备返回ACK表示自己已经接收。
控制传输无数据PID序列
控制传输无数据PID序列比较简单,没有数据事务。所以状态阶段使用IN事务,用于反馈主机的请求。
这里我们使用SET_ADDRESS分析具体的事务过程:
主要使用SETU令牌使用DATA0数据包发送USB的SET_ADDRESS请求,设备接收后状态阶的IN事务使用DATA1数据包序列反馈给主机。