2. UHCI 协议基础:帧格式、SOF 令牌、数据传输与握手包详解

UHCI(Universal Host Controller Interface)是 Intel 定义的 USB 1.x 全速/低速主机控制器接口标准。在嵌入式调试场景中,UHCI 因其寄存器级可控、DMA 友好、帧周期固定等特点,常被用作调试通道的物理层载体。理解 UHCI 的帧结构、令牌包、数据阶段和握手机制,是实现可靠 DMA 协同传输的前提。

2.1 UHCI 帧格式与帧周期

UHCI 以 1 ms 为基本时间单位组织总线流量,每个帧(Frame)由主机控制器发送的 SOF(Start of Frame) 令牌起始,随后是若干个事务(Transaction)。帧的编号由主机维护,范围 0–1023,循环使用。

帧属性 值 说明
帧周期 1 ms 固定间隔,由主机内部定时器触发
帧号范围 0–1023 11 位计数器,溢出后归零
SOF 位置 帧起始 广播至所有设备,用于同步
帧内事务数 动态 由帧列表(Frame List)调度决定
调试端口启示: 1 ms 帧周期为 DMA 提供了天然的时间分片边界。调试数据可在每帧的预留时间段内批量传输,避免干扰正常 USB 通信。
UHCI 帧周期结构(1 ms) 帧 N SOF + 事务 帧 N+1 SOF + 事务 帧 N+2 SOF + 事务 帧 N+3 SOF + 事务 时间轴(1 ms 间隔) 帧号 0→1023 循环,SOF 携带当前帧号

2.2 SOF 令牌包详解

SOF(Start of Frame)是 UHCI 每帧发送的第一个包,由主机控制器广播至所有设备。SOF 包格式如下:

字段 位数 值/含义
PID 8 0xA5(SOF 标识)
帧号 11 当前帧编号(0–1023)
CRC5 5 帧号校验
EOP — 包结束信号(SE0)
调试端口关键点: SOF 的帧号字段可被调试固件用于时间戳标记。DMA 控制器可监听 SOF 中断,实现与主机帧周期的硬件同步,避免软件轮询。
SOF 令牌包结构 PID (8 bit) 0xA5 帧号 (11 bit) 0–1023 CRC5 5 bit EOP SE0 SOF 由主机广播,所有设备接收,用于帧同步和帧号更新

2.3 数据传输阶段

UHCI 的数据传输发生在 SOF 之后,由主机调度事务(Transaction)。每个事务包含三个阶段:

  1. 令牌阶段(Token): 主机发送令牌包(IN/OUT/SETUP),指定端点地址和传输方向。
  2. 数据阶段(Data): 数据发送方(主机或设备)发送 DATA0/DATA1 数据包,最大 64 字节(全速)。
  3. 握手阶段(Handshake): 接收方返回握手包(ACK/NAK/STALL/NYET),确认传输结果。
阶段 发送方 包类型 长度
令牌 主机 IN / OUT / SETUP 4 字节
数据 主机或设备 DATA0 / DATA1 0–64 字节
握手 接收方 ACK / NAK / STALL / NYET 1 字节
DMA 协同注意: 数据阶段是 DMA 传输的主要目标。DMA 控制器应配置为在令牌阶段完成后自动启动数据搬移,并在握手阶段前完成数据准备。若设备 NAK,DMA 应暂停并等待重试,避免总线冲突。
UHCI 事务三阶段(以 IN 为例) 令牌阶段 主机 → 设备 (IN) 数据阶段 设备 → 主机 (DATA) 握手阶段 主机 → 设备 (ACK) DMA 在数据阶段介入:令牌解析后启动 DMA 读/写,握手前完成数据搬移 若设备 NAK,DMA 暂停并等待下一帧重试

2.4 握手包详解

握手包是事务的最后一个阶段,由接收方返回,长度固定为 1 字节(PID 字段)。UHCI 定义了四种握手包:

握手包 PID 值 含义 调试场景影响
ACK 0xD2 数据正确接收,事务成功 DMA 可确认传输完成,释放缓冲区
NAK 0x5A 设备忙,无法接收/发送数据 DMA 应重试,避免数据丢失
STALL 0x1E 端点出错,需主机软件干预 DMA 应停止传输,触发错误处理
NYET 0x96 未准备好(仅用于高速模式) 全速 UHCI 不使用,可忽略
嵌入式调试策略: 调试端口应优先处理 ACK,对 NAK 实现硬件自动重试(最多 3 次),对 STALL 立即上报错误状态。DMA 描述符链中可嵌入握手状态字段,供固件事后分析。
握手包状态机与 DMA 协同 ACK NAK STALL NYET DMA 动作:ACK → 完成并释放描述符;NAK → 硬件重试(≤3 次);STALL → 停止并报错 NYET 在全速 UHCI 中无效,DMA 可忽略

2.5 帧列表与事务调度

UHCI 使用 帧列表(Frame List) 管理每帧的事务。帧列表是一个 1024 项的指针数组,每项指向一个传输描述符(TD)链。主机控制器按帧号索引帧列表,依次执行链上的所有 TD。

组件 说明 调试端口作用
帧列表基址 主机内存中的 4 KB 对齐区域 DMA 可预取帧列表,减少延迟
帧列表项 32 位指针,指向 TD 链首 调试端口可动态修改指针,插入调试事务
传输描述符 (TD) 描述一个事务的令牌、数据、握手信息 DMA 直接操作 TD 字段,实现零拷贝
队列头 (QH) 用于批量/控制传输的队列管理 调试数据可复用 QH 机制,避免冲突
DMA 协同设计: 将调试端口的 TD 链放置在 DMA 可访问的内存区域,利用 DMA 的链表传输模式(Scatter-Gather)自动遍历 TD,无需 CPU 逐项处理。
帧列表与 TD 链结构 帧列表 Frame 0 Frame 1 ... Frame 1023 TD 1 令牌+数据+握手 TD 2 令牌+数据+握手 ... DMA 协同要点 1. DMA 预取帧列表项 2. DMA 遍历 TD 链 3. 每帧执行链上所有 TD 4. 调试 TD 可动态插入 5. 握手状态反馈至 DMA

2.6 本章小结

  • UHCI 帧周期固定为 1 ms,SOF 令牌广播帧号,用于总线同步。
  • 每个事务包含令牌、数据、握手三个阶段,DMA 可在数据阶段介入。
  • 握手包 ACK/NAK/STALL 决定 DMA 的后续动作:完成、重试或报错。
  • 帧列表 + TD 链结构为 DMA 提供了可预取、可遍历的硬件调度机制。
  • 嵌入式调试端口可借助 UHCI 的帧周期和 TD 链,实现低延迟、零拷贝的数据传输。