面向 UFS 3.1 + LPDDR4X 合封 (JEDEC uMCP)的固件驱动设计约定 ------ 覆盖 双器件独立初始化 、LUN 与 Boot LU 、UTP 命令队列 、WriteBooster 掉电风险 、 LPDDR4X 训练与刷新 与 热耦合温控,逐条给出可落地的流程、判据与超时预算。
2套独立总线
6路电源域
11.67Gbps / lane
297ball FBGA
| 文档编号 | uMCP-SW-SPEC-001 |
| 版本 / 状态 | V1.0 · 正式发布 |
| 适用器件 | JEDEC uMCP(UFS 2.1 / 2.2 / 3.0 / 3.1 + LPDDR4 / LPDDR4X / LPDDR5),典型配置 UFS 3.1 + LPDDR4X,254 / 297 / 315-ball FBGA |
| 参考标准 | JESD220C(UFS 3.1)· UFSHCI 3.0 · UniPro 1.8 · M-PHY 4.1 · JESD209-4B(LPDDR4 / 4X) |
| 配套文档 | uMCP_电路设计指南.html(原理图 / 电源时序 / PCB Layout / 热设计 / 焊接) |
|---|
0. 目的与范围
本规范约束 uMCP 器件在嵌入式固件中的软件行为 :初始化顺序、LUN 与 Boot 配置、 命令提交与同步语义、掉电与热管理、DRAM 训练与刷新。凡本文与器件 datasheet / JEDEC 规范冲突,以 datasheet 为准。
- 统一启动顺序:固化「电源 → REF_CLK → 释放复位 → UFS 链路训练 → 读 SPL → 训练 DRAM → 加载系统」这条不可颠倒的链。
- 统一同步语义 :明确 WriteBooster 开启时「写完成 ≠ 已落盘」,关键数据必须
SYNCHRONIZE CACHE。 - 统一错误恢复阶梯:任务 → LUN → 器件 → 链路 → 硬件复位,逐级升级,不越级、不静默。
- 统一掉电与热策略:给出写窗口、提交协议、休眠唤醒顺序,以及 UFS 与 DRAM 之间的双向热耦合对策。
不在本规范范围:原理图、电源时序、PCB Layout 与焊接(见《uMCP 电路设计指南》); 文件系统与 FTL 的算法选型;UFS Host 控制器 IP 的 RTL 设计与 PHY 寄存器级调试细节。
一句话结论:uMCP 是**「一颗封装里两个互不认识的世界」** ------ UFS 走 M-PHY + UniPro + UTP + SCSI 四层协议栈,LPDDR4X 走并行训练总线,两者封装内部没有任何信号互连 。 没有 SYNCHRONIZE CACHE 的写入不等于落盘,没有完整训练的 DRAM 在高低温下必然出错,带着未初始化 DRAM 继续启动会在后续随机崩溃。
文档使用说明
- 本文是《uMCP 电路设计指南》的软件配套篇:硬件篇解决「怎么供电、怎么走线、怎么散热」,本文解决「驱动怎么写、两侧怎么配合、异常怎么救」。
- 协议分层、命令集、描述符与属性均按 JEDEC JESD220C(UFS 3.1) 与 UFSHCI 3.0 描述。不同料号在 LUN 数量、Gear 档位、WriteBooster 支持上存在差异,移植前必须逐条核对器件 Device Descriptor。
- 文中 C 代码为协议骨架伪代码 ,演示流程与判断条件,非特定平台可直接编译的完整实现;
ufshci_*、dram_mr_write()等为平台相关底层。
贯穿全文的三条铁律
① 先 UFS 后 DRAM,顺序不可颠倒 ------BootROM 只有片内 SRAM,必须先从 UFS 的 Boot LU 取到 SPL,才可能训练 DRAM; ② 开了 WriteBooster 就必须显式同步 ------写入返回成功只代表进了 SLC 缓存,不等于持久化; ③ 两侧都要有独立的超时与失败处理 ------任一侧失败都必须给出明确指示(点灯 / 串口日志 / 进下载模式),不能静默继续。
1 · 器件定位与双器件架构
uMCP 不是「更快的 eMMC」。它把 UFS 存储与 LPDDR 内存装进同一个封装,对外呈现两组电气与协议完全独立的接口。软件设计的第一件事,是认清「哪些是共用的、哪些是分开的」。
1.1 一颗封装、两套总线
uMCP 内部两颗独立芯片:UFS(存储)与 LPDDR(内存),封装内无信号互连PMIC六路电源 + 上电时序SoC / AP• UFS Host(M-PHY + UniPro)• LPDDR4X 控制器• REF_CLK 输出(常供)• GPIO(RST_n 等)• 掉电检测中断uMCP · 297-ball FBGAUFS dieNAND + UFS 控制器VCC / VCCQ / VCCQ2M-PHY 差分 TX / RX协议:SCSI over UTP软件:UFS 驱动必须先初始化LPDDR4X dieDRAM 阵列 + 控制逻辑VDD1 / VDD2 / VDDQCA / DQ / DQS / CLK协议:命令真值表软件:训练 + MRS由 SPL 训练TX/RXCA/DQ封装内部 UFS 与 DRAM 无任何信号互连,仅 VSS 共地 ------ 必须分别初始化、分别超时、分别失败处理
图 1 · uMCP 双器件架构:共用封装与地,各自独立的电源、总线与协议栈
1.2 关键参数与软件视角
2 套
完全独立的总线
UFS 串行差分 + LPDDR 并行,封装内仅共地
6 路
需独立管理的电源轨
VCC / VCCQ / VCCQ2 / VDD1 / VDD2 / VDDQ
11.67
Gbps / lane(HS-G4)
2 lane 全双工,聚合 23.3 Gbps
297
焊球数(UFS 3.1 + LPDDR4X)
0.4 / 0.5 mm pitch,约 12 × 12 mm
0.6 V
LPDDR4X 的 VDDQ
裕量最小,混料会直接烧器件
32
UTP 命令队列深度上限
MCQ 模式下更高,需按描述符确认
80 %
建议容量使用率上限
给 FTL 留 GC 与磨损均衡空间
200
随机掉电测试次数下限
关键数据可恢复率须 100 %
参数取自《uMCP 电路设计指南》第 1~3 章与 JEDEC JESD220C;具体料号以 Device Descriptor 读回值为准。
1.3 六路电源域的软件可见性
电源是硬件的事,但每一路都会以某种形式反映到软件行为上。驱动必须知道哪些现象对应哪一路电源的问题:
| 电源轨 | 归属 | 典型电压 | 软件可见的失效表现 |
|---|---|---|---|
| VCC | UFS | 2.5 / 3.3 V | 链路能建但读写报介质错误;写入中途 VCC 跌落 → 映射结构损坏 |
| VCCQ | UFS | 1.2 V(UFS 3.x) | UFS 控制器不响应;Host 寄存器读写返回全 F |
| VCCQ2 | UFS | 1.8 V(M-PHY 模拟) | 链路训练直接失败,存储「完全不存在」 |
| VDD1 | LPDDR | 1.8 V | 训练不收敛;降速后仍不稳定 |
| VDD2 | LPDDR | 1.1 V | 大电流突发下压降 → 高负载时才出现读写错 |
| VDDQ | LPDDR | LPDDR4: 1.1 V / 4X: 0.6 V | Vref 训练找不到有效窗口;读写零星比特错误 |
软件排查的基本原则:先看电源与时钟,再怀疑协议
uMCP 的 Bring-up 故障里,绝大多数不是协议问题 。按《uMCP 电路设计指南》5.3 的 Bring-up 顺序查: 六路电源实测 → REF_CLK 实测 → RST_n 实测 → UFS 能否枚举 → 链路档位 → DRAM 训练。 前三项占实际故障的绝大多数,第 4 项只在设计本身有缺陷时才是主因。
1.4 与 eMCP 的关键差异(移植必读)
| 维度 | eMCP(eMMC + LPDDR) | uMCP(UFS + LPDDR) | 移植后果 |
|---|---|---|---|
| 存储接口 | 11 根并行单端,半双工 | 2~3 对串行差分,全双工 | 驱动栈完全不同,不可复用 |
| 时钟 | 主控给 CLK,可随时降频 / 暂停 | REF_CLK 固定频率,必须常供 | 休眠时关时钟 → 唤醒后链路重训 |
| 上电可用 | 上电后给时钟即可发命令 | 必须完成 M-PHY Link Startup | 未训练前存储完全不可访问 |
| 命令模型 | CMD / 响应,单命令串行 | UTP + UTRD 队列,可多命令并发 | 需管理每个命令的完成回调与超时 |
| Boot 区 | 硬件固定 Boot Partition | Boot LU 需配置并使能(bBootLunEn) | 量产漏配 → 完全不启动 |
| 写缓存 | eMMC Cache(需 flush) | WriteBooster(SLC 缓存,需同步) | 未同步掉电 → 数据丢失 |
| 省电态 | Sleep / PowerDown | 增加 Hibern8 链路休眠 | 退出需唤醒时序,有恢复延迟 |
| DRAM 侧 | LPDDR3 / 4 / 4X | LPDDR4 / 4X / 5 | 训练流程与刷新率需重新适配 |
一句话区分
eMCP 与 uMCP 的区别只在存储那一半 :eMMC 是并行单端,UFS 是串行差分。 DRAM 那一半(LPDDR)的设计规则基本一致。所以从 eMCP 转到 uMCP,要重学的是 UFS 侧,DRAM 侧的经验可以平移。
2 · 术语与缩写
UFS 的术语体系与 eMMC 几乎不重叠。本章统一口径,避免「LU / LUN / Boot / 描述符」在文档与代码里指的不是同一件事。
2.1 协议与命令术语
| 缩写 / 术语 | 全称 | 本文中的含义 |
|---|---|---|
| uMCP | UFS-based Multi-Chip Package | UFS 存储 die + LPDDR DRAM die 合封在一个 FBGA 内 |
| M-PHY | --- | 物理层;PWM 模式用于初始化,HS-G1~G4 用于正常工作 |
| Gear | 速率档 | M-PHY 的工作速率档位:HS-G1(1.46)~ HS-G4(11.67 Gbps/lane) |
| UniPro | Unified Protocol | 数据链路 / 传输层;负责端口、流控与电源模式协商 |
| UTP | UFS Transport Protocol | 传输层;用 UTRD 描述一个命令,用 UPIU 承载具体内容 |
| UTRD | UTP Transfer Request Descriptor | 命令描述符,位于主机内存;写门铃寄存器即提交命令 |
| UPIU | UFS Protocol Information Unit | 协议信息单元:COMMAND / RESPONSE / DATA-IN / DATA-OUT / TASK MGMT 等 |
| LUN | Logical Unit Number | 逻辑单元编号(0~7,其中 0xB0 系列为 Well-Known LU) |
| LU | Logical Unit | 逻辑单元本体,一个独立的 SCSI 逻辑设备;与 LUN 常被混用 |
| Boot LU | Boot Logical Unit | 存放 SPL 的专用 LU,A / B 两份互为备份 |
| RPMB | Replay Protected Memory Block | 防重放认证存储;HMAC-SHA256 认证,密钥一次性烧写 |
| WriteBooster | --- | UFS 3.x 的 SLC 写缓存加速;写入先进缓存,返回后再搬运 |
| Hibern8 | Hibernate | UniPro 链路休眠,M-PHY 进入省电态;退出需唤醒时序 |
| Descriptor | 描述符 | 只读的结构化信息块:Device / Configuration / Unit / Geometry / Health |
| Flag | 标志 | 布尔型开关(读 / 写 / 置位 / 清零 / 切换):bBootLunEn、fPowerOnWPEn |
| Attribute | 属性 | 数值型参数:bCurrentPowerMode、bAvailableWriteBoosterBufferSize |
| UNMAP | --- | SCSI 命令,等价于 eMMC 的 Trim;告知器件数据块不再需要 |
| FFU | Field Firmware Update | 器件固件在线升级;过程绝对不能掉电 |
| ZQ | ZQ Calibration | DRAM 输出驱动强度与 ODT 的校准;基准电阻 240 Ω ±1 % |
| WL / DQS Gate | Write Leveling / DQS Gate Training | DRAM 训练项:补偿 CLK-DQS 偏差 / 确定 DQS 有效采样窗口 |
| tREFI | Refresh Interval | DRAM 刷新间隔;随温度档缩短 |
| SPL | Secondary Program Loader | 二级引导程序;存放在 Boot LU,由 BootROM 读入片内 SRAM |
2.2 本文书写约定
- 命令名 沿用 SCSI / UFS 规范的大写形式(如
READ (10)、SYNCHRONIZE CACHE (10)、UNMAP),不带h后缀------UFS 没有「命令码字节」的概念,命令以 CDB 形式封装在 UPIU 里。 - 描述符 / 标志 / 属性 按其命名前缀书写:
b= 1 字节、w= 2 字节、d= 4 字节、q= 8 字节;f开头的标志为布尔型。 - 速率档 写作
HS-G4/PWM-G1;「11.67 Gbps」均指单 lane 线速率,2 lane 聚合值会显式标注。 - 时序量级以「数 ms / 数十 ms / 数百 ms」给出------不同料号与不同 SoC 差异较大,绝对值须以实测与手册为准。
- 代码示例为 C 伪代码,省略控制器寄存器底层实现,只表达流程与判据。
3 · 驱动架构与配置载体
UFS 驱动比 eMMC 多两层:命令队列管理和设备配置管理。这两层放错位置,后面所有优化都是白做。
3.1 分层职责
| 层 | 职责 | 禁止做的事 |
|---|---|---|
| 应用层 | 业务读写文件 / 分区;不感知 LUN 与缓存 | 直接拼 CDB、直接操作门铃寄存器 |
| 文件系统层 | 日志 / 事务;删除时下发 UNMAP |
绕过 sync 语义宣称数据已持久化 |
| 块设备与 LUN 管理层 | LUN 枚举与映射、Boot LU 选择、RPMB 认证、健康度轮询 | 硬编码 LUN 编号;忽略 WriteBooster 状态 |
| UFS 协议层(UTP) | 构造 UTRD / UPIU、提交门铃、管理完成回调与超时 | 提交命令后不做超时回收;忽略 RESPONSE UPIU 状态 |
| Host 控制器层(UFSHCI) | 寄存器配置、中断、DMA 描述符环 | 在链路活动期间门控 REF_CLK |
| UniPro + M-PHY 层 | Link Startup、Power Mode Change、Hibern8 进出 | 不做降档重试直接判定器件损坏 |
| DRAM 驱动 / 训练模块 | MRS 配置、ZQ 校准、各项训练、刷新率调节、自刷新进出 | 跳过训练项;固定刷新率不随温度调整 |
3.2 UFS 协议栈四层分工
UFS 协议栈四层:软件直接打交道的只有最上两层软件Application / SCSI 命令集READ(10/16) · WRITE(10/16) · UNMAP · SYNCHRONIZE CACHE · FORMAT UNIT文件系统块设备层软件UTP(UFS Transport Protocol)UTRD 门铃提交 · UPIU 承载命令/数据/响应 · 任务管理 · 队列并发UFS 驱动UTP 层软+硬UniPro(数据链路 / 传输层)L4 端口 · 流控 · 错误恢复 · 电源模式(Hibern8)协商主控硬件+ 固件硬件M-PHY(物理层)PWM-G1 初始化 · HS-G1~G4 协商 · 差分链路 · Link StartupPHY + PCB阻抗 / REF_CLK分层排查原则:性能问题看上两层;「存储完全不存在」看下两层(电源 / REF_CLK / 链路)
图 2 · UFS 协议栈四层:硬件只需把 M-PHY 做对,软件只需把 UTP 写对
3.3 描述符 / 标志 / 属性:三种配置载体
UFS 的配置没有「一个寄存器搞定」这回事,而是分成三类载体,访问方式各不相同。分不清这三类,是所有 UFS 配置错误的根源。
三类配置载体:只读信息用描述符,布尔开关用标志,数值参数用属性Descriptor描述符 · 只读访问方式QUERY REQUEST(读)典型成员Device / ConfigurationUnit / GeometryHealth / String用途:能力探查Flag标志 · 布尔开关访问方式SET / CLEAR / TOGGLE典型成员bBootLunEnfPowerOnWPEnfPermanentWPEn用途:功能开关Attribute属性 · 数值参数访问方式WRITE / READ(按位宽)典型成员bCurrentPowerModebActiveICCLevelbAvailWriteBoosterBufSize用途:运行期调节配置改变通常需要器件复位后才生效;部分配置(永久写保护、OTP 类)不可逆
图 3 · 描述符 / 标志 / 属性:三类载体的访问方式与典型成员
命名前缀就是位宽说明
UFS 的标识符前缀直接告诉你它的大小:b = 1 字节、w = 2 字节、d = 4 字节、q = 8 字节,f 开头的是布尔标志。 写代码时不要凭感觉定义变量宽度 ------把 dNumDynamicLU(4 字节)用 uint8_t 去读,读回来的是截断值。
4 · 上电初始化与 Bring-up
uMCP 的启动有一条不可颠倒的链路。任何一步没过,后面都不可能发生------这是它与分立式方案最大的不同。
4.1 不可颠倒的启动链
冷启动全链路:任何一步不过,后面都不可能发生① PMIC 六路上电VCC → VCCQ → VCCQ2 → VDD1 / VDD2 / VDDQ 依次斜升,每路单调② REF_CLK 起振稳定19.2 / 26 / 38.4 MHz,必须在 RST_n 释放之前 稳定,且持续供给③ 释放 RST_n低有效;所有电源稳定后再释放,留足余量④ M-PHY Link Startup器件自动完成链路训练;未完成时存储完全不可访问⑤ BootROM 从 Boot LU 读 SPLbBootLunEn 必须已使能;A / B 双份,失败自动切换另一份⑥ SPL 训练 LPDDR4X 并加载后续镜像ZQ → Write Leveling → DQS Gate → Read/Write Training → Vref → 校验容量顺序不可颠倒:必须先从 UFS 取到 SPL,才可能训练 DRAM
图 4 · uMCP 冷启动链:UFS 通了再谈 DRAM
4.2 UFS 侧初始化流程
上电后器件处于未配置状态:链路刚跑在最低速的 PWM-G1,Boot LU 未使能,WriteBooster 状态未定,LUN 布局需自行读取。初始化必须按下列顺序执行:
- 等待 Link Startup 完成 :轮询 Host 控制器状态,确认链路已从 PWM-G1 协商到目标 Gear。此步不由软件驱动,硬件自动完成,软件只做确认与超时。
- 读 Device Descriptor:拿到版本、LUN 数、容量、支持的 Gear、WriteBooster 支持位等(见 4.3)。
- 校验能力是否达标 :若协商到的 Gear 低于预期,先记日志再继续,不要直接判定失败------降档运行比不启动好。
- 枚举 Unit Descriptor :逐个 LUN 读单元描述符,建立
lun_id → 用途映射,不硬编码编号。 - 配置 Boot LU 并使能 :写
bBootLunEn;Boot LU 建议同时设fPowerOnWPEn上电写保护。 - 配置 WriteBooster:按产品策略决定开关(见第 7 章);若开启,同步配置缓存水位监控。
- 读 Health Descriptor :记录
bDeviceLifeTimeEstA/B与bPreEOLInfo作为基线。 - 验证读写:对 User LU 做一次小规模读写回环,确认链路与协议均可用。
/* uMCP 冷启动:UFS 先行,返回 0 表示成功 */
int umcp_boot_init(void)
{
ufs_dev_t dev;
/* ① 电源与时钟由硬件 / PMIC 完成,软件只做确认 */
if (!power_rails_ready()) return -E_POWER;
if (!refclk_stable()) return -E_CLK;
/* ② 等待 M-PHY Link Startup(硬件自动完成,软件只看结果) */
if (ufshci_wait_linkup(LINKUP_TIMEOUT_MS) != 0)
return -E_LINKUP; /* 绝大多数是电源 / REF_CLK / RST_n 问题 */
/* ③ 读 Device Descriptor 识别器件能力 */
if (ufs_read_dev_desc(&dev) != 0) return -E_NODEV;
if (dev.b_num_lu == 0) return -E_NODEV;
/* ④ 枚举 LUN:从描述符读,不硬编码 */
if (ufs_enum_units(&dev) != 0) return -E_LUNCFG;
/* ⑤ 配置并使能 Boot LU,同时开上电写保护 */
if (ufs_write_flag(F_BOOT_LUN_EN, 1) != 0) return -E_BOOTCFG;
if (ufs_set_boot_wp() != 0) return -E_BOOTCFG;
/* ⑥ 按产品策略配置 WriteBooster */
if (g_wb_enable) {
if (ufs_write_attr(B_WB_BUF_RESIZE, g_wb_size) != 0)
return -E_FEATURE;
}
ufs_write_flag(F_WRITE_BOOSTER_EN, g_wb_enable);
/* ⑦ 记录健康度基线 */
ufs_read_health_desc(&dev.health);
return 0; /* 此后才由 SPL 训练 DRAM */
}
初始化里最容易漏的两件事
① bBootLunEn 没有使能。 UFS 与 eMMC 不同:eMMC 的 Boot 分区是硬件固定的,而 UFS 的 Boot LU 必须先配置并使能 。 量产时只烧数据、漏配 Boot LU,板子上电后 BootROM 找不到 SPL,表现为**「完全不启动」**。首次点亮新料号时尤其容易踩------器件是新的,Boot LU 可能还是出厂默认状态。
② Link Startup 超时被当成「器件坏了」。 链路训练失败的表现是「存储完全不存在」,而不是「速率慢」。遇到它,先查六路电源、REF_CLK、RST_n 这三项,前三项占实际故障的绝大多数。
4.3 器件识别:读 Device Descriptor
Descriptor 是唯一可靠的能力来源。把页大小、LUN 数、Gear 硬编码进驱动,换料就要改代码。
| 字段 | 含义 | 软件用途 |
|---|---|---|
| bLength / bDescriptorIDN | 描述符长度与类型 | 校验读到的是不是想要的描述符 |
| bDeviceSubClass / bDeviceClass | 设备类别 | 确认是 UFS 存储设备(Embedded / Removable / Disk) |
| wSpecVersion | UFS 版本 | 判定支持哪些特性(3.1 才有 WriteBooster 完整能力) |
| bNumberLU | LUN 数量 | 枚举范围,不可硬编码 |
| bBootEnable | Boot 功能是否使能 | 与 bBootLunEn 联动判断 Boot 可用性 |
| dNumDynamicLU / wNumberOfBlocks | 可配置 LU 数 / 逻辑块数 | 容量与分区规划依据 |
| bSupportedWriteBooster | WriteBooster 支持位 | 决定第 7 章策略是否可执行 |
| bSupportedGear / bMaxGear | 支持的速率档 | 与实际协商档位比对,判断是否存在硬件降档 |
| iManufacturerName / iProductName | 厂商 / 型号字符串索引 | 配合 String Descriptor 读出可读型号 |
用 String Descriptor 做型号识别
读 ID 类命令在 UFS 里没有等价物。要识别具体料号,应读 String Descriptor (由 iProductName 索引),把型号字符串解析出来并记入日志。 现场返修时,这条日志能直接区分「换了料号」还是「同一料号批量退化」。
4.4 LPDDR4X 侧初始化与训练
DRAM 训练由 SPL 软件完成,硬件的职责是提供足够的信号裕量。五个训练项一个都不能省:
LPDDR4X 训练五步:任一项跳过,常温下可能能跑,高低温下必然出错① ZQ 校准240 Ω ±1 %驱动强度 / ODT基准② Write Leveling补偿 CLK 与DQS 飞行时间偏差③ DQS Gate确定 DQS有效采样窗口位置④ 读写训练寻找 DQ 相对DQS 最佳采样点数据眼图⑤ Vref 训练寻找接收端参考电压最佳值含 DQ + CA训练失败 → 降速重试先降一档频率重试完整流程;多档都失败才报硬件故障训练通过 ≠ 稳定ZQ 用 5 % 电阻时训练可能勉强通过,但读写不稳定结束后校验容量位宽与预期不符 → 贴错料 / 混料(LPDDR4 vs 4X,VDDQ 不同)绝不允许「跳过训练直接用默认参数跑」常温下可能能跑,高低温、高负载、老化后必然出现零星比特错误 ------ 这类错误无法定位,代价最高
图 5 · LPDDR4X 训练五步与三条硬约束
/* DRAM 初始化:完整训练 + 降速重试 */
int dram_init(void)
{
const uint32_t freqs[] = { TARGET_FREQ, TARGET_FREQ / 2, SAFE_FREQ };
int i;
dram_power_up(); /* 电源斜升 -> 时钟稳定 -> 复位 -> 释放 */
dram_mr_init(); /* 模式寄存器基本配置 */
for (i = 0; i < 3; i++) {
dram_set_freq(freqs[i]);
if (zq_calibrate() != 0) continue; /* ① */
if (write_leveling() != 0) continue; /* ② */
if (dqs_gate_training() != 0) continue; /* ③ */
if (read_write_training() != 0) continue; /* ④ */
if (vref_training() != 0) continue; /* ⑤ */
if (dram_check_size() != 0) /* 容量 / 位宽校验 */
return -E_DRAM_MISMATCH;
return 0; /* 训练成功,记录实际运行频率 */
}
return -E_DRAM_TRAIN; /* 三档全失败 -> 硬件问题,不静默继续 */
}
4.5 失败分级处理
uMCP 两侧各自都要有明确的失败出口。带着未初始化的 DRAM 继续启动,会在后续以随机崩溃的形式暴露,是最难查的一类故障。
| 失败阶段 | 典型原因 | 推荐动作 | 禁止动作 |
|---|---|---|---|
| 六路电源未就绪 | PMIC 未使能 / 某路漏设计 | 串口打印具体缺失的电源轨,停机 | 重试几次后继续 |
| Link Startup 超时 | VCCQ2 处理错 / REF_CLK 缺失或频率错 | 打印电源与时钟实测结果,进下载模式 | 判定器件损坏 |
| 器件识别失败 | 描述符读取异常 / 型号不符 | 打印读回的原始描述符,停机 | 用默认值兜底继续 |
| Boot LU 读取失败 | bBootLunEn 未使能 / A 份损坏 |
自动切换到 B 份;两份都失败进下载模式 | 只重试 A 份 |
| DRAM 训练失败 | 参数表与料号不符 / 三路 DRAM 电源异常 | 降速重试全部档位;仍失败则停机并打印训练日志 | 跳过训练继续启动 |
| 容量位宽不符 | 贴错料 / LPDDR4 与 4X 混料 | 停机并明确指出「料号不符」 | 按实际容量继续跑 |
两侧都要有可观测的失败指示
上电后 BootROM 只有片内 SRAM 可用,很多平台连串口都还没初始化。此时失败指示要靠点灯 / GPIO 电平 / 进入下载模式这些最朴素的手段。 「板子上电毫无反应」和「板子上电后闪三下灯」在产线上的排查效率差一个数量级------这一点必须在固件设计阶段规划好,而不是等量产卡住了再补。
后续章节请下载「芯参谋」查看
......(篇幅原因, 还有16章· 详见芯参谋→方案设计)
当前分享仅开放前 5 章正文。详细资料请在芯参谋客户端中打开完整文档。
打开路径:🔧解决方案&应用市场分析 -> 原理方案设计 -> uMCP_软件设计规范