3、UFS协议栈详解:物理层、链路层、传输层
UFS 协议栈是个分层结构,从上到下依次是:传输层(Transport Layer)、链路层(Link Layer)和物理层(Physical Layer),简称 T-L-P。每一层各司其职,又紧密配合。
我个人刚接触 UFS 的时候,脑子里第一反应是“这和串行 ATA 有什么区别?”后来踩了几个坑才明白——UFS 协议栈其实更像一个微缩的通信网络,而不是简单的存储控制器。
先看一张整体框图,把这三层的关系搞明白。
3.1 物理层(PHY)—— 最底下的一层
物理层就是 UFS 硬件的“电线层”,负责把 0/1 比特流通过差分信号串行传输。它用的是 MIPI M-PHY 规范。
我当年调 UFS 板级信号的时候,最头疼的就是 M-PHY 的 Gear 切换。UFS 支持多种速率(Gear 1/2/3/4/5 等等),每次升档都得重新校准。有一次主机端 Gear 切换频率不匹配,导致链路锁不住,折腾了我整整三天。
物理层关键参数:
| 参数 | 说明 | 典型值 |
|---|---|---|
| 速率模式 | HS-Gear1 ~ HS-Gear5 | HS-Gear4 约 11.6 Gbps/lane |
| Lane 数 | 1 或 2 条差分对 | 大多用 1 lane 简化设计 |
| 信号电平 | HS 模式 200-400 mV 差分 | 低功耗 PWM 模式更低 |
| 编码方式 | 8b/10b 编码(早期) → 128b/130b(HS-Gear4+) | 后者效率更高 |
⚠ 曾经遇到的坑:我有一版 PCB 走线差分阻抗控制没做好,结果链路层 CRC 频繁报错。一开始怀疑芯片问题,最后拿示波器一量,眼图都塌了。所以物理层的差分对齐和阻抗匹配,千万别省。
3.2 链路层(Link Layer)—— 承上启下
链路层基于 MIPI UniPro 规范。它的任务可不少:流控、重传、分包、帧定界……说白了,就是保证物理层传过来的比特流能被上层(传输层)识别,不出错。
UniPro 协议栈也分几个小子层,比如 CPORT(通用端口层)、DL(数据链路层)、PHY Adapter(物理层适配器)。不过我们在开发中通常只关心数据链路层提供的服务:
- 分段与重组(SAR):传输层的 UPIU 可能很大,链路层会切成若干小段(segment),每段加头部和 CRC。
- 重传机制:一旦物理层丢包,链路层会自动请求重发,上层完全无感。
- 流量控制:接收方通过信用(Credit)机制告诉发送方“我能收多少”,防止缓冲区溢出。
💡 我自己的调试技巧:抓 UFS 协议分析仪的时候,如果看到大量 CRC 错误和重传,大概率是物理层信号质量差。链路层只是尽力而为,它不会修复物理层的问题,只能不断重试。所以先查眼图,再查协议,别搞反。
这里有一个概念容易混淆:UFS 的链路层重传和传输层的重传到底是什么关系?
我个人理解:链路层重传的是“片段”,传输层重传的是“整个 UPIU”。链路层重传很快(微秒级),如果链路层重传搞不定,才会触发传输层超时。所以你想想看,底层可靠性越高,上层越省心。
3.3 传输层(Transport Layer)—— 协议命令的搬运工
传输层对应 UFS 协议规范(JESD220 系列)中的 UFS Transport Protocol(UTP)。它定义了 UPIU(UFS Protocol Information Unit)的格式。
所有 SCSI 命令、任务管理、数据、状态都封装在 UPIU 里透传。传输层不关心底层用几根线跑多少速度,它只负责把 UPIU 发出去,再收回来。
UPIU 有几种常见类型:
- Command UPIU:SCSI 命令(比如 READ/WRITE)
- Response UPIU:设备响应(状态、sense 数据)
- Data In/Out UPIU:实际数据载荷
- Task Management UPIU:任务管理(比如 abort)
我们写固件的时候,最常打交道的就是这些 UPIU 的组装和解析。我记得早期做 NVMe 转 UFS 桥接时,因为对 UPIU 的头部字段理解不透彻(比如 Expected Data Transfer Length 算错了),导致大量命令超时。后来把每个 UPIU 字段一一打印出来对规格书,才找到 bug。
🔍 传输层的“会话”概念:UFS 主机和设备之间会维护一条逻辑连接,叫做“UFS Interconnect”。传输层负责管理这个连接的建立、保持、断开。不过实际调试中,我很少手动干预传输层,更多是关注链路的协商结果。
| 层级 | 负责的内容 | 典型协议/规范 |
|---|---|---|
| 传输层 | UPIU 封装、命令调度、超时重试 | UFS Transport Protocol (UTP) |
| 链路层 | 分段、流控、重传、帧定界 | MIPI UniPro |
| 物理层 | 信号编码、差分传输、Gear/速率切换 | MIPI M-PHY |
嗯,梳理下来其实 UFS 的三层分工非常干净。物理层解决“怎么传比特”,链路层解决“怎么不丢不错”,传输层解决“上层命令怎么走”。没有哪一层能跳过去——我们做嵌入式驱动的,每层都要熟悉它的行为边界,才能定位问题。