中断split事务序列
中断split传输事务的IN和OUT和bulk/control的大体类似,但中断事务由于有实效性要求,故不得在全速总线上进行本地重传。
OUT事务


用大白话给你翻译一下中断OUT拆分事务到底是怎么回事:
1. 主机怎么发数据?
主机(电脑)要把数据发给一个慢速设备(比如USB键盘的指示灯、鼠标的自定义功能),它不能直接发到慢速总线上,而是先走高速总线发给集线器里的TT(中转站)。
发的时候分两步:
- “开始拆分”:主机告诉TT“我要发数据了”,并把数据包传给TT。
- “完成拆分”:之后主机再问TT“数据发下去了吗?设备收到了没?”
2. TT怎么处理?
TT有个排队缓存区,按顺序存放主机发来的多个“开始拆分”任务。
- 它不会立刻就发给慢速设备,而是等到当前这个微帧(125微秒的小时间段)结束时,才开始按顺序把任务转发到慢速总线上。
- 如果慢速设备处理得慢、或者数据多导致发送超时,没发完的任务就顺延到下一个微帧继续发。
3. 数据校验:错了就直接扔
主机发数据时带了一个CRC校验码
- TT收到后先检查这个校验码:如果对不上,直接丢弃这个任务,绝不转发给慢速设备。
- 主机那边等半天没收到“完成拆分”的回应,会超时,但不会像发文件那样重试三次——因为中断数据讲究实时性,过期了重发也没意义。
4. 一个例子帮你脑补
你电脑上插了一个USB复古游戏手柄(全速设备)。游戏里你按下一个按键:
- 主机瞬间生成一个“按键数据包”,通过高速总线发给集线器的TT。
- TT检查CRC没问题,放进排队区。
- 当前微帧结束时,TT把这个任务转发给游戏手柄。
- 手柄收到后回复“收到了”,TT把结果存起来。
- 主机发“完成拆分”来取结果,知道按键已送达。
如果中间CRC校验失败:
- TT直接扔掉数据,不转发。
- 主机超时,但不会重发——因为游戏按键按下那一刻已经过了,重发一个“之前的按键”也没用。
总结
中断OUT就是:主机按固定节奏把数据包交给TT,TT排队后转发给慢速设备。数据错了就丢,不重试;时间不够就顺延。主打一个“实时优先,错过了就错过”。
IN事务


这段话讲的是中断IN拆分事务(主机从慢速设备读取数据)。用大白话解释如下:
核心流程:主机从慢设备读数据
第一步:主机发“开始拆分”
主机告诉TT:“我要从某个慢速设备(如鼠标、键盘)读数据”。
TT把这个“读指令”存到开始拆分流水线里,按顺序排队。
第二步:TT去慢速总线上读数据
在下一个微帧开始时,TT按排队顺序,逐个去慢速总线上向设备发读请求。
设备回应:可能返回数据、也可能返回NAK(忙)、STALL(出错)、或者没反应(超时)。
TT把这些结果(数据/状态)存到完成拆分流水线里。
第三步:主机发“完成拆分”取数据
在后续的微帧里,主机不断发“完成拆分”指令,从TT那里取结果:
情况A:事务没跨微帧
设备在一个微帧内就返回了数据 → TT在下一次“完成拆分”响应时,一次性把数据还给主机。情况B:事务跨了微帧(数据较大,一个微帧发不完)
TT需要两次“完成拆分”才能把完整数据给主机:- 第一次返回 MDATA(意思是“还没完,下一个微帧继续”),这个阶段不做CRC校验(因为数据还没收全)。
- 第二次返回 DATA0/DATA1(数据收全了),此时才做CRC校验。如果CRC通过,返回数据;如果失败,返回ERR(错误)。
特殊情况:CRC校验失败
- 如果TT在慢速总线上收到数据但CRC校验失败,不会返回数据,而是直接返回ERR握手包给主机。
- 主机收到ERR,就知道这次读取失败了。
- 如果是跨微帧的情况:第一次可能已经正常返回了MDATA,但第二次返回ERR → 主机必须丢弃第一次收到的数据,当作整个事务失败。
中断IN就是:主机先下“读指令”订单,TT去慢设备那取货。货小就一次送回,货大就分两次送(第一次说“还没完”,第二次才给货)。校验失败就直接报错,分两次送的那种如果第二次失败,第一次的也得扔掉。
中断IN vs 中断OUT
| 维度 | 中断OUT(主机发数据给设备) | 中断IN(主机从设备读数据) |
|---|---|---|
| 开始拆分携带什么 | 数据包 + CRC | 只有读指令,无数据 |
| 慢速总线动作 | TT转发数据给设备 | TT向设备请求数据 |
| 完成拆分返回什么 | 握手状态(ACK/NAK/STALL) | 数据(或ERR/NAK/STALL) |
| 能否跨微帧 | 一般不能(数据一次性下发) | 能(数据较大时分两次返回) |
| 分两次返回时的标识 | 不适用 | 第一次用MDATA,第二次用DATA0/1 |
| CRC失败后果 | 丢弃不下发,主机超时 | 返回ERR,主机知道失败 |
USB2.0集线器HUB





