能读 ID 但读写失败 · 样机排查手册
编制日期 2026-09-21 | 版本号 Rev 1.0
XTX 芯天下 · FAE 现场技术文档 | 样机阶段 ID 读得到但 Read / Program / Erase 失败(SPI NOR / SPI NAND / SD NAND / eMMC)| 2026-09 版
命令码、状态寄存器位号与极性、dummy cycle 数、总线宽度切换命令、ECC 与 OOB 布局,全部以所用型号的 datasheet 与主控平台手册为准;本文只讲排查机制与分工。
- 本文的前提是ID 已经读得到——链路是通的,问题在读 ID 没有覆盖到的协议层、配置层与数据层。
- 文中出现的状态位名称(忙位、写使能位、块保护位、QE 位)是各介质的常见叫法,具体位号、所在寄存器编号与有效电平逐条核对 datasheet,本文不给出可直接照抄的位定义。
- 涉及清状态寄存器、改一次性可编程区域、解除保护的操作在多数器件上不可逆,见第 3 章危险操作提示。
- 任何降级手段(降频、退单线)都只是定位手段,不是最终方案,验收必须回到目标配置。
一句话结论:能读 ID 只证明了「链路通」——芯片有电、被选中、时钟到位、命令能进能出。而读写要多满足四层:协议对(模式与命令序列)、配置对(QE / 地址宽度 / dummy cycle)、状态清(忙已结束、写已使能、保护已解)、供电够(写入瞬间不跌落)。所以排查本质是用降级把这四层逐层剥开,而不是在高速四线模式下一遍遍重试。
这份文档解决什么
解决ID / CID 读回正确,但 Read / Program / Erase 失败、超时、校验不过或数据错乱这一类问题,覆盖 SPI NOR / SPI NAND / SD NAND / eMMC 四种介质。第 6 章是可直接翻查的现象速查表,第 7 章是可带进车间的核查清单与结案栏。
怎么用这份文档
- 先确认「读是好的」:ID 读得到之外,普通读也要能返回正确数据。连读都不对,问题在配置层。
- 按四刀顺序降级:降频单线 → 查状态参数 → 写擦最小回路 → 查供电带载,每刀都有退出条件。
- 绕开上层做最小回路:不要一上来就在文件系统里拷大文件,那会把协议、坏块与电源问题混在一起。
- 一次只改一个变量:频率、线宽、模式、地址宽度每次只动一处。
- 降级只是定位不是方案:找到根因后必须回到目标配置重新验收并全温区复验。
1. 问题本质:读 ID 与读写的门槛差
这一章解决一个认知问题:为什么 ID 读得到,读写却会挂。读 ID 对时序与配置的要求低到近乎没有,它验证的只是「链路通」;而读写要在链路之上多满足四层条件。理解这道门槛差,就不会在最高配置下一遍遍重试。
1.1 读 ID 通过,到底证明了什么
把「读 ID 成功」翻译成具体的物理事实,只有下面这几条。凡是表格里没有的,都没有被验证过。
| 读 ID 成功证明了 | 它没有证明 |
|---|---|
| 芯片有电,电压能支撑基本逻辑 | 写入 / 擦除瞬间大电流下电压是否还稳 |
| 片选、时钟、数据线都通且方向正确 | 高速或四线模式下信号完整性是否够 |
| 主控发的命令码器件认得 | 读数据所需的 dummy cycle 与模式配套 |
| 器件能在低速命令下回数据 | 写使能、忙轮询、保护状态是否正确 |
| —— | 页大小、OOB、ECC、坏块表与驱动是否一致 |
读正常、写失败是这一章最典型的画像。读和写在物理上就是两件不同的事:读只需要器件回数据,写需要器件内部的电荷泵工作、需要额外的电流、需要更长的时间。所以「读得好好的,一写就挂」往往指向供电带载、写使能或保护位,而不是信号完整性。
1.2 读写新引入的四层要求
读写相对读 ID 多出来的要求,可以归成四层。排查时按从上层到下层的顺序收敛:先确认协议与配置(便宜、好改),最后才动供电与布线(贵、慢)。
| 层次 | 要求 | 不满足时的典型表现 | 验证成本 |
|---|---|---|---|
| 协议 | SPI 模式(极性 / 相位)、命令序列完整 | 低速单线正常,一提速或换模式就挂 | 低:改配置即可 |
| 配置 | QE、地址宽度、dummy cycle 与命令配套 | 读出来有数据但整体错乱或偏移 | 低:改配置即可 |
| 状态 | 忙已结束、写已使能、保护已解除 | 写入静默失败,回读仍是旧数据 | 低:读状态寄存器 |
| 供电 | 写 / 擦瞬间电压不跌落,去耦充足 | 读正常写失败,降频后好转 | 高:要改板或加电容 |
注意最后一行:供电层的验证成本最高,所以才要用降频这一刀先把它和其它三层分开——降频能削减瞬时电流与时序压力,降下来就好了,根因大概率在物理层。
1.3 三种介质各自的重点
SPI NOR 最容易出在配置层——四线模式、地址宽度、dummy cycle 全靠配置位与命令配套,配错就是数据错乱;SPI NAND 最容易出在数据层——页大小、OOB 布局、ECC 强度、坏块表必须和驱动完全一致;eMMC / SD 最容易出在协议层——总线宽度与速率模式需要双方切换成功,1-bit 能过不代表 4-bit 能过。抓重点可以少走一半弯路。
2. 快速分流:降级定位四刀
本章是整份文档的主干。四刀的设计原则是先便宜后昂贵、先软件后硬件:第一刀只改一个配置参数,第二刀只读回几个字节,第三刀需要逻辑分析仪,第四刀才需要示波器看电源。
2.1 四刀的判据与退出条件
| 刀次 | 动作 | 合格判据(达标才往下走) | 不达标时的处置 |
|---|---|---|---|
| ① 降频单线 | 把时钟降到最低档、退回单线模式再测 | 低速单线下读写完全正常 | 仍失败 → 与时序无关,转第 ② 刀 |
| ② 查状态参数 | 读状态寄存器与参数页,逐字段对齐 datasheet | 忙位已清、写使能已置、保护未生效 | 异常 → 先解保护、等忙、改配置 |
| ③ 最小回路 | 绕开文件系统,单次写一页、擦一块直测 | 单页写读逐字节一致 | 失败 → 抓包看命令序列缺哪一段 |
| ④ 查供电带载 | 示波器抓 Program 期间的 VCC 纹波与跌落 | 跌落幅度在 datasheet 允许范围内 | 超标 → 加去耦、查 LDO 带载能力 |
降频、退单线、关 ECC 校验,全部只是定位手段,目的是把某一层单独隔离出来。找到根因之后,必须回到目标配置(目标频率、目标线宽、开启 ECC)重新验收,并在全温区复验。把「降频能用」当成交付结论,是把问题从样机阶段推到量产阶段的标准做法。
2.2 先固化复现条件
读写失败常常是条件性的:某个地址段失败、某种数据花样失败、某个温度下失败、大批量写才失败。没有固化的复现条件,就无法判断改动是否有效。
| 要固化的项 | 怎么写下来 | 用途 |
|---|---|---|
| 失败地址 | 记录失败的逻辑地址与物理页 / 块号 | 判断固定地址还是随机 |
| 数据花样 | 全 00、全 FF、递增、随机各测一遍 | 判断是否与位翻转相关 |
| 操作规模 | 单页、单块、全片各测一遍 | 判断是否与耗时或温升相关 |
| 环境条件 | 常温、高温、低温、电压拉偏 | 判断是否裕量不足 |
| 复现概率 | 跑 N 次失败 M 次 | 作为改动后的对比基准 |
偶发失败不要用「这次过了」当结论。先测出基线失败率(例如跑 100 次失败 8 次),改动后再测同样次数。只有失败率降到 0 且样本量足够,才算这一刀见效。
3. 第 2 刀 · 状态寄存器与参数页回读
这一刀性价比最高:不需要额外仪器,只要把器件当前的状态与配置读回来,再和 datasheet 逐项对上,就能判掉一大半读写失败。核心动作只有一句——把「读到的」和「该有的」逐项比对。
- 位号、所在寄存器编号、有效电平全部以 datasheet 为准。常见的状态寄存器里,忙位与写使能位通常在第一个状态字节,块保护位与四线使能位的位置因厂牌而异,本文不给出可照抄的位定义。
- 清状态寄存器、改写一次性可编程区域、解除读/写保护在多数器件上不可逆,且解除保护往往伴随全片擦除。执行前必须确认:该操作在所用型号上的确切后果、是否有回退路径、板上的数据是否已经备份。
- 不要为了「试试看」而批量改状态位——一次只改一个位,改完读回确认,再改下一个。
3.1 SPI NOR:状态位、保护位与模式位
SPI NOR 的读写失败,绝大多数能在状态寄存器里找到答案。按「忙 → 写使能 → 保护 → 模式」的顺序逐项看。
| 要看的状态 | 它是什么 | 不对时的表现 | 处置 |
|---|---|---|---|
| 忙位 | 标示器件是否还在执行上一操作 | 写入后立即读回旧数据或报错 | 轮询到忙位清零再发下一条命令 |
| 写使能位 | 标示器件是否接受了写使能命令 | 写入完全无效且状态位无报错 | 每次 Program / Erase 前重发写使能 |
| 块保护位 | 按区间锁住部分或全部存储区 | 部分地址写不进,其余正常 | 按 datasheet 解除对应区间保护 |
| 四线使能位 QE | 决定器件是否接受四线命令 | 单线全正常,切四线后错乱 | 按 datasheet 置位后再切四线 |
| 地址宽度配置 | 决定用 3 字节还是 4 字节地址 | 超过 16 MB 后高位地址异常 | 核对容量与地址模式是否匹配 |
上面表格里的名称是各介质的常见叫法,具体位号与极性以 datasheet 为准。
3.2 SPI NAND:OIP、ECC、坏块与参数页
SPI NAND 比 NOR 多一层数据组织:页大小、OOB 布局、ECC 强度、坏块标记位置,只要有一项和驱动配置不一致,读出来的数据本身就是错的。
| 要看的项 | 怎么核对 | 不一致时的表现 |
|---|---|---|
| 页大小与 OOB 大小 | 从参数页读出,与驱动配置逐项比对 | 读回数据偏移、校验失败 |
| ECC 强度与使能状态 | 核对器件要求的 ECC 与主控 ECC 模块配置 | 报不可纠错误,或读出数据有零星错误 |
| 坏块标记 | 扫描各块首个页的 OOB,与驱动的坏块表比对 | 坏块表不一致,数据被写进坏块 |
| 操作进行位 OIP | 写 / 擦之后轮询直到清零 | 后续命令被忽略,写入失败 |
怀疑 ECC 配置问题时,一个有效的定位手段是暂时关闭 ECC 校验,直接读出原始数据和 OOB:原始数据本身是对的,说明问题在 ECC 配置;原始数据就错了,说明问题在前级的时序或地址。这只是定位手段,最终必须带着正确的 ECC 配置重新验收。
3.3 eMMC / SD:状态、总线宽度与速率模式
eMMC / SD 侧的「配置」主要体现在总线宽度与速率模式上,两者都需要主控与器件双方切换成功才算生效。最常见的情况是:1-bit 低速枚举与读写都正常,一切到 4-bit 或高速模式就挂。
| 排查项 | 方法 | 判据 |
|---|---|---|
| 器件是否就绪 | 读器件状态,确认不在忙、不在编程态 | 状态返回就绪且无错误位 |
| 总线宽度 | 先用 1-bit 跑通,再切 4-bit / 8-bit 复测 | 切换后读写与 1-bit 结果一致 |
| 速率模式 | 从最低速起,逐级提速并在每级复测 | 每级都通过才继续提速 |
| 切换是否生效 | 切换后读回相关状态并校验 | 回读值与目标模式一致 |
具体的切换命令编号与时序要求以 JEDEC 规范与所用型号的 datasheet 为准。
3.4 实操:通用命令示意
下面给出的是排查动作的顺序示意,不是可直接照抄的命令——不同平台、不同工具的命令名与参数完全不同,请以所用平台的文档为准。
# 1) 读状态寄存器(命令码以 datasheet 为准):
# busy=1 -> 上一操作还没结束,等它清零
# wel =0 -> 写使能没发,每次写/擦前都要先发
# 2) 轮询忙位到清零(务必设超时,不要死等)
for i in range(MAX_RETRY):
sr = read_status_register()
if not (sr & BUSY_MASK):
break
delay_ms(1)
else:
fail("busy timeout") # 超时即失败,不要继续往下发命令
# 3) 写使能 -> 写/擦 -> 再轮询忙位 -> 回读比对
write_enable()
program_page(addr, data) # 或 block_erase(addr)
wait_busy_clear()
assert read_page(addr) == data # 不一致先查地址宽度与页边界
# 4) 保护位:一次只改一位,改完读回确认4. 第 3 刀 · 写擦最小回路与抓包
这一刀解决「问题到底在驱动还是在上层」:绕开文件系统、绕开多分区、绕开量产流程,用最短的命令序列做一次单页写与一次单块擦,同时用逻辑分析仪把命令序列完整抓下来。
4.1 什么叫「最小回路」
最小回路的定义是:只包含这次验证必需的东西。凡是能去掉的都要去掉,去掉之后仍然失败,才能把问题锁定在器件与主控之间。
| 维度 | 最小回路取值 | 为什么要这样 |
|---|---|---|
| 操作对象 | 单颗芯片,单页写 / 单块擦 | 排除多片选、多器件干扰 |
| 软件层次 | 直接调底层驱动,不用文件系统 | 排除缓存、映射、坏块管理 |
| 时钟与线宽 | 最低时钟 + 单线 | 排除时序裕量与 QE 配置问题 |
| 数据量 | 一页,先写全 00 再写全 FF | 花样简单,便于逐字节比对 |
| 电源 | 板上原供电,去耦已确认 | 与最终状态保持一致 |
4.2 抓包要看的三段
一次成功的写入,在逻辑分析仪上必须是完整三段。缺任何一段,都能直接定位到驱动的具体疏漏。
| 段 | 抓包上应该看到什么 | 缺了它说明什么 |
|---|---|---|
| 写使能 | 片选拉低 → 写使能命令 → 片选拉高 | 驱动没发写使能,写入必然静默失败 |
| 页编程 / 块擦除 | 片选拉低 → 编程或擦除命令 + 地址 + 数据 → 片选拉高 | 命令或地址不对,先核对命令码与地址宽度 |
| 读状态轮询 | 片选反复拉低读状态,直到忙位清零 | 驱动没等忙结束就发下一条命令 |
| (可选)回读比对 | 读命令 + 地址 + 读出数据 | 没有回读比对,问题会被推迟到量产才暴露 |
三段都在,顺序错了同样会失败:写完没等忙就回读、擦之前忘了写使能、片选在两个命令之间没有拉高(器件没收到命令边界)。抓包时要逐段确认片选边界——每条命令都必须有自己的片选低脉冲。
4.3 判据与退出
| 判据 | 达标标准 | 不达标时的下一步 |
|---|---|---|
| 最小回路写入成功 | 单页写后回读逐字节一致,连续多次通过 | 抓包看三段缺哪一段 |
| 最小回路擦除成功 | 擦除后回读为擦除后的默认电平 | 核对擦除命令与块地址对齐 |
| 提升数据量仍成功 | 扩到多页、多块仍全部通过 | 查坏块管理与地址映射 |
| 回到目标配置仍成功 | 恢复目标频率与线宽后全部通过 | 查信号完整性与供电裕量 |
最小回路通过,证明器件、链路、底层驱动都是好的,问题在上层:文件系统、坏块管理、分区表、多器件片选切换、或量产流程里的擦写顺序。这时就把重心从硬件转到软件配置上。