eMMC / SD 首次枚举失败 · 样机排查手册
编制日期 2026-09-21 | 版本号 Rev 1.0
XTX 芯天下 · FAE 现场技术文档 | eMMC / SD NAND / SD 卡首次上电枚举失败的分段定位与根治 | 2026-09 版
命令码、寄存器字段、上电时序数值、上拉阻值全部以 JEDEC 标准与器件 datasheet 为准;本文只回答「要查哪一类、按什么顺序查」。
- 本文讨论的是首次上电枚举失败(连器件身份都没认下来),不是「能识别但读写错」。后者请转《能读ID但读写失败_样机排查》。
- 文中出现的命令码(CMD0 / CMD1 / CMD2 / CMD3 / CMD6 / CMD7 / CMD8 / CMD9、ACMD6 / ACMD41、CMD11)与响应类型(R1 / R2 / R3 / R7)是各介质的通用写法,不同器件、不同主控 SDK 的实现细节会有差异,动手前逐条核对。
- EXT_CSD / CSD / OCR / SCR 的字段偏移与字节序、上电时序参数(上升时间、等待窗口、busy 超时上限)的上限下限,一律以 datasheet 为准,本文不给出未经核实的数字。
- Linux 侧的
dmesg文本随内核版本、控制器驱动、设备树配置而变,第 6 章给出的是关键字方向,不是逐字匹配模板。
这份文档解决什么
解决的是样机第一次上电,eMMC / SD NAND / SD 卡连「身份」都没被主控认下来这一类问题的定位与根治方法。 覆盖三类高发场景:换料后第一次贴板、飞线 / 转接板引出的样机、参考设计照抄但电源域改过的板子。
全文按「机制 → 决策树 → 分成因排查 → 速查表 → 核查清单」组织。
第 2 章的决策树是定位主线,第 6 章是可直接翻查的速查表与 dmesg 关键字对照,第 7 章是可带进车间的核查清单与结案栏模板。
一句话结论:枚举失败不是「芯片坏了」,而是一条串行命令链断在了某一条上。 定位动作只有一个——找到日志 / 波形里最后一条成功执行的命令,失败点就在它的下一步。 而样机阶段最高频的三个断点高度集中:DAT0 上拉电阻缺失(器件永远在「忙」)、 VCC 与 VCCQ 的上电时序不满足(器件还没醒)、 4-bit / 高速切换时 DAT1~DAT3 或信号完整性没跟上(低速能跑,一提速就死)。 先强制 1-bit + 低速跑通,再逐级加宽提速,是唯一不会走弯路的顺序。
1. 机制:枚举是一条串行命令链
eMMC 和 SD 都不是「上电就认」,而是主控按固定顺序发一串命令、器件逐条应答的过程; 任何一条没应答,后面全部不成立。定位的第一步不是换芯片,而是确定断在第几条。
1.1 两介质的命令序列对照
eMMC 与 SD 的前半段(复位、取 CID、分配地址)语义相近,但协商方式完全不同:
eMMC 用 CMD1 反复轮询 OCR 里的 busy 位;SD 先发 CMD8 探测电压与协议版本,
再用 ACMD41(带 CMD55 前缀)轮询。这个差异决定了两条泳道的失败点位置不一样,
排查时必须先分清介质,不要混着套。
| 阶段 | eMMC(MMC 总线) | SD / SD NAND(SD 总线) | 断在这一段的典型表现 |
|---|---|---|---|
| 0 · 上电与复位 | VCC 与 VCCQ 建立,复位释放;常见要求电源稳定后等待约 1 ms 再发第一条命令 | VCC 建立,卡检测完成;常见要求上电后先给约 74 个时钟再发第一条命令 | 完全无响应,串口连控制器探测日志都没有 |
| 1 · 进入 Idle | CMD0(GO_IDLE_STATE) | CMD0(GO_IDLE_STATE) | CMD 线上有波形发出,但看不到任何回读 |
| 2 · 电压与能力协商 | CMD1(SEND_OP_COND)携带 OCR,轮询 busy 位直到释放 | CMD8(SEND_IF_COND)探测电压与版本,随后 ACMD41 轮询 busy 位 | OCR 回读超时,或 busy 位一直不释放 |
| 3 · 身份与地址 | CMD2(ALL_SEND_CID)→ CMD3(SET_RELATIVE_ADDR) | CMD2(ALL_SEND_CID)→ CMD3(SEND_RELATIVE_ADDR) | CID 全 0 / 全 F,或地址分配后立刻失联 |
| 4 · 读取几何参数 | CMD9(SEND_CSD)→ CMD7(SELECT_CARD)→ CMD8(SEND_EXT_CSD) | CMD9(SEND_CSD)→ CMD7(SELECT_CARD) | CSD / EXT_CSD 报 CRC 错,容量识别不符 |
| 5 · 宽度与速率 | CMD6(SWITCH)写总线宽度与速率模式字段 | ACMD6(SET_BUS_WIDTH)与 CMD6(SWITCH_FUNC) | 低速可用,一切宽或提速立刻失败 |
表里「常见要求」一列给出的都是量级与顺序,不是具体数值。 例如 SD 侧「上电后先给约 74 个时钟再发第一条命令」、eMMC 侧「电源稳定后等待约 1 ms 再发第一条命令」, 这两条是工程上最常被引用的要求,实际数值以 datasheet 与主控 SDK 的实现为准。
1.2 逐段拆解与各自的失败画像
把上表再压缩成「每一段断掉会长什么样」,就是下面的分段画像。 现场最快的做法是:先看串口日志里最后一条成功打印,把失败段落锁死,再进对应的成因章节。
| 段 | 这一段在做什么 | 断掉的画像 | 下一步去哪 |
|---|---|---|---|
| 0 上电复位 | 让器件从无电状态进入可接收命令的状态 | 串口没有任何 mmc 相关打印,示波器 CMD 线上也只有主控侧的波形 | 第 3 章 |
| 1 进入 Idle | 把器件拉回已知初始态 | 有波形但无回读;或回读恒为全 1 | 第 3 章(先查上拉) |
| 2 协商 | 谈电压域、寻址方式、容量类别 | OCR 读得到但 busy 位不释放;或压根读不到 OCR | 第 3 章 |
| 3 身份地址 | 取 128 位 CID,分配相对地址 | CID 值明显异常(全 0 / 全 F / 位翻转) | 第 4 章 |
| 4 几何参数 | 取 CSD / EXT_CSD,驱动据此算容量与时序 | 报 CRC 错;或容量识别与标称不符 | 第 4 章 |
| 5 宽度速率 | 从 1-bit 低速切到 4/8-bit 与高速模式 | 低速一切正常,切完立刻超时或 CRC 暴增 | 第 5 章 |
样机阶段最容易犯的错,是拿一块从没成功过的板子反复试。 正确做法是先抓一份基线:能正常枚举那块板的启动日志、CID / CSD 回读值、 设备树里 mmc 节点的配置、实测的 VCC / VCCQ 电压与上电波形、CLK 与 CMD 的实测波形,各存一份。 后面所有对比都以它为基准,定位速度会快一个数量级。
2. 决策树:先断在哪一段
拿到一块枚举失败的样机,不要按「可能的原因」逐条猜,而是按最后一条成功的命令 把失败点收敛到 A / B / C 三类之一,再进对应的成因章节。这棵树的作用是把猜测变成判定。
怎么用这棵树
- 先分清介质:eMMC 与 SD 的协商段完全不同,套错泳道会得出完全错误的结论。 看原理图与料号,不要凭封装猜。
- 取最后一条成功的命令:串口日志、控制器调试打印、逻辑分析仪的 SPI/SD 解码,三者任选其一, 关键是拿到「成功/失败」的分界点,而不是只看有没有打印。
- 按 A / B / C 归类后只查对应章节:A 类查供电与物理层,B 类查协商与线序, C 类查切换与信号完整性。跨类排查是样机阶段最浪费时间的动作。
- 一次只改一个变量:改完重新上电、重新抓日志。 同一次改三处,成功了你不知道是哪处立的功,失败了也不知道是哪处背的锅。
现场经常看到「低速也起不来,却在反复调设备树里的速率与总线宽度」。 如果 1-bit + 最低速率都跑不通,那一定是 A 类或 B 类问题, 此时调速率只是把同一个失败换了个报错文本。先确认最低配置能跑通,再谈提速。
3. 成因一:CMD1 / ACMD41 无响应
这一段失败的表现是「器件永远在忙」或者「器件根本没醒」, 根因高度集中在三处:DAT0 上拉缺失、VCC 与 VCCQ 时序不满足、复位释放后等待不足。
3.1 原理:busy 位与 DAT0 是同一件事
器件上电后需要一段内部初始化时间,这段时间它无法接受命令。协议用两种方式把这个状态告诉主控:
一是OCR 响应里的 busy 位(位 31,具体位置以协议文本为准),主控靠反复重发 CMD1 / ACMD41 轮询;
二是把 DAT0 拉低,主控可以直接看电平判断忙闲。
这里有一个极易被忽略的硬件前提:DAT0 是被开漏驱动 + 外部上拉拉高的。 如果 DAT0 上没有上拉电阻(常见规格是 10 kΩ 量级,范围以平台参考设计为准), 器件释放 DAT0 之后这条线不会自己回到高电平,主控会一直读到低电平, 于是判定「器件永远忙」,轮询超时,枚举在第一段就死掉。
结论很硬:DAT0 上拉缺失是样机阶段枚举失败的头号根因,而且症状极具迷惑性—— 波形上看得到主控在发命令、看得到器件有回应,就是「永远忙」。
VCCQ 是另一处高频断点。eMMC 有两路电源:VCC 供内核、VCCQ 供接口 I/O。 两路的建立顺序、间隔、上升斜率在 datasheet 里都有要求。样机上最常见的错误是: 板子只有一路电源,VCCQ 通过一个 0 Ω 电阻或磁珠从 VCC 分出来, 上电时两路几乎同时爬升但没有满足 datasheet 要求的先后顺序; 或者 VCCQ 这一路的 LDO 使能脚比 VCC 晚释放,导致接口电源姗姗来迟。
3.2 实操:按供电 → 时序 → 上拉的顺序查
- 测电压,不看原理图看实测:上电后用万用表量 VCC 与 VCCQ 的稳态值, 用示波器量两路的相对上电顺序与上升沿。要求:两路都落在 datasheet 规定的范围内, 且顺序与间隔满足要求。测点要在器件引脚端,不是电源输出端。
- 核对复位释放时序:复位信号的释放必须发生在两路电源都稳定之后, 且释放后要留出 datasheet 要求的等待时间再发第一条命令。 很多 SDK 里的延时是照抄参考板的,换了电源方案就失效了。
- 逐条查上拉:用万用表通断档或看原理图,确认 CMD 与所有用到的 DAT 线都有上拉。 DAT0 必须有,4-bit 模式下 DAT1~DAT3 也要有,8-bit 模式下 DAT4~DAT7 同样。 阻值按平台参考设计,常见的量级是 10 kΩ ~ 100 kΩ。
- 看 DAT0 的实际电平:上电后不接任何命令,直接量 DAT0。 如果它一直是低电平,先怀疑上拉缺失或器件没上电,而不是怀疑协议栈。
- 延长轮询超时做交叉验证:把主控侧的初始化超时临时放大数倍, 如果能枚举成功,说明器件只是在慢慢初始化,属于时序裕量问题,不是硬件错。
- 禁止在器件 busy 期间反复硬复位或频繁上下电。器件在内部初始化时被打断, 可能进入异常状态,后续连正常的波形都抓不到,把定位引向完全错误的方向。
- 禁止用导线或镊子短接 VCC 与 VCCQ 强制上电。两路的电压域不同 (VCCQ 常见为 1.8 V 或 3.3 V),短接会直接损坏器件接口。
- 禁止在 SD 卡带电时插拔。卡座的热插拔依赖检测引脚与电源缓启动电路, 样机直连的卡座往往没做这套保护,带电插拔的浪涌会打坏卡或主控接口。
- 禁止为提高成功率而把上拉换成极小阻值(例如 1 kΩ 以下)。 这会显著增加功耗并让边沿变差,反而引入新的信号完整性问题。
3.3 验证:怎么证明这一段真的过了
- 示波器同时抓 VCC、VCCQ、RST#、DAT0 四路,确认顺序与间隔满足 datasheet 要求,截图存档。
- DAT0 在轮询结束后稳定回到高电平,且高电平幅度接近 VCCQ(不是悬空的中间电平)。
- 把初始化超时放大后能枚举成功,说明是裕量问题;放大后仍失败,一定是硬件层问题。
- 连续上下电 20 次以上全部枚举成功,才算这一段真正过。 只成功一两次的,属于「碰运气通过」,不算。
- 把上拉电阻的位号、阻值、实测电压写进调试记录,不要只写「已检查上拉」。
4. 成因二:CMD8 无响应与 CID / CSD 读取错
器件醒过来了、也进了 Idle,但协商阶段谈不拢或者身份信息读回来是错的。 这一段的根因集中在:电压域与信号电平协商失败、CMD / DAT 线序交叉、上拉缺失导致的响应边沿劣化。
4.1 原理:电压协商与长响应的脆弱点
SD 侧的 CMD8 是一次「互相试探」:主控告诉器件自己能提供什么电压,
器件如果接受就把电压信息与检查图案回传。这一步没有响应,通常意味着三件事之一:
器件不是 SD 系器件(拿 eMMC 的时序去读 SD,或反过来)、
电压域不在器件接受范围内、物理层根本没把命令送过去。
再往后是 1.8 V 信令切换。SD 侧在 ACMD41 里用 S18R 请求 1.8 V 信令,
器件用 S18A 应答,双方谈成才发 CMD11 切电压。
这一步失败在 UHS 卡上非常常见,表现是日志里出现 1.8 V 信令切换失败的报错,
但器件以默认速率其实是可以正常工作的——所以「1.8 V 切换失败」要区分「不支持」与「支持但电路没跟上」。
CID / CSD 的读取则是长响应(R2 类型,128 位)。长响应对物理层的要求远高于短响应: 任何一位的边沿劣化都会导致 CRC 校验失败。所以经常出现的现象是—— 短命令(CMD0 / CMD1)都能过,一到读 CID / CSD 就报 CRC 错, 这几乎一定是信号完整性或上拉问题,而不是协议栈问题。
4.2 实操:线序、上拉与卡座三方核对
线序核对(飞线与转接板场景必做)
样机用飞线或转接板把器件接到主控上时,线序交叉是头号杀手。 必须逐根核对,不能靠「颜色对颜色」。
| 信号 | 主控侧引脚 | 器件侧引脚 | 核对方法 | 交叉后的症状 |
|---|---|---|---|---|
| CLK | 按原理图确认 | CLK | 万用表通断档逐根量 | 完全无响应 |
| CMD | 按原理图确认 | CMD / DI | 通断 + 看波形是否双向 | 命令无回读 |
| DAT0 | 按原理图确认 | DAT0 / DO | 通断 + 上电后量电平 | 永远 busy |
| DAT1 | 按原理图确认 | DAT1 / WP# | 通断(易与写保护混淆) | 1-bit 可用、4-bit 死 |
| DAT2 | 按原理图确认 | DAT2 / HOLD# | 通断(易与保持混淆) | 1-bit 可用、4-bit 死 |
| DAT3 | 按原理图确认 | DAT3 / CS# | 通断(易与片选混淆) | 1-bit 可用、4-bit 死 |
上拉与卡座
- 逐条确认上拉位置:上拉必须放在靠近器件或靠近主控的合理位置, 放在飞线中段等于没放。
- 卡座接触:SD 卡座的弹片在样机上非常容易接触不良, 表现为「偶尔能认、偶尔不能」。用同一张卡换个已知好板交叉验证,能立刻区分是卡座还是器件。
- 卡本身:换一张已知好的卡。样机阶段拿一张在别处反复烧过的旧卡来调, 卡本身可能已经有坏块或处于异常状态。
- 电平转换电路:主控 1.8 V、器件 3.3 V(或反之)时, 中间的电平转换芯片方向、使能、速率能力都要核。很多电平转换芯片跑不到高速模式的速率。
4.3 验证:读回比对而不是「能启动就算过」
- 回读 CID 并与丝印 / 料号比对:厂商 ID 与器件 ID 要对得上。 读回来是全 0 或全 F,说明物理层没通,不是器件坏了。
- 回读 CSD 与容量:解析出的容量必须与器件标称容量一致。 出现「容量正好是标称的一半」或「大得离谱」,是寻址方式(字节 / 扇区)没谈拢的典型症状。
- eMMC 侧回读 EXT_CSD:确认版本、容量字段、器件支持的能力位图与 datasheet 一致。
- 降速交叉验证:把时钟降到最低(识别阶段通常是 400 kHz 量级), 如果低速能读对、高速读错,就是信号完整性问题,不是协议问题。
- 连续 20 次冷启动全部读到一致的 CID。读到两次不一样的值,说明链路处在临界状态。
有些平台在枚举失败后会退回默认参数继续启动,看起来系统起来了, 实际上是用一个错的参数在跑——容量不对、速率不对、宽度不对。 验收标准必须是回读值比对,不是「系统能进命令行」。