只读分享解决方案文档调试&解决方案📅 2026-09-21🔖 Rev 1.0⏳ 29天有效(至 2026-10-31)
🔧解决方案&应用市场分析 -> 调试&解决方案 -> 存储_样机问题测试 -> SPI_NAND_首次启动失败_样机排查

SPI_NAND_首次启动失败_样机排查

生成时间 2026-09-28 13:34:58 有效期至 2026-10-31 23:59:59(29天有效(至 2026-10-31))

SPI NAND 首次启动失败 · 样机排查手册

编制日期 2026-09-21 | 版本号 Rev 1.0

XTX 芯天下 · FAE 样机 bring-up 技术文档 | 面向第一次上电 / 手焊 / 飞线场景 | 2026-09 版

技术事实核查纪律(动手前必读)

页大小、块大小、OOB 大小与布局、ECC 算法与强度、上电等待时间、BootROM 的 BOOT 区范围与读取策略 —— 全部以器件 datasheet 与主控平台手册为准。本文只讲机制与定位方法,不代替 datasheet。

  • SPI NAND 的页 / 块 / OOB 参数没有统一值:页常见 2 KB / 4 KB,一块常见 64 或 128 页,OOB 常见 64 / 128 / 256 字节 —— 都只是常见值,必须逐颗核对该料号 datasheet。
  • ECC 是 NAND 的生死线:算法(BCH / RS 一类)、纠错强度、校验码放在 OOB 的哪个偏移,由烧录器、BootROM、驱动三方约定,任一方不一致都是「能烧不能启」。
  • BootROM 读 NAND 的行为是平台固化的:BOOT 区包含多少个 block、是否跳坏块、是否做多副本、用片内 ECC 还是软件 ECC,以主控厂商的 TRM / BootROM 手册与 SDK 源码为准。
  • 本文出现的所有命令码与参数均为常见写法示例,不是通用常量;凡标注「以手册为准」的条目,现场必须复核后再动手。
5 步
BootROM 读一个页的序列
上电等待 → 复位读 ID → 读页 → 轮询 → 读缓存
ECC
NAND 的生死线
算法强度与 OOB 布局三方必须一致
BOOT 区
BootROM 只看固定范围
前若干个 block,具体以平台手册为准
坏块
出厂即存在,会新增
烧录器跳过 = 数据整体前移 = BootROM 读错位
页 / 块
必须三方一致
烧录器、BootROM、驱动同一套参数
4 步
手工定位法
读 ID → 读页回读 → 比对 → 扫坏块表

一句话结论:SPI NAND 起不来,绝大多数不是「数据没烧进去」,而是「烧进去的位置、ECC 的算法、坏块的处理方式」与 BootROM 期望的不一致。NOR 是「给个地址就给你数据」,NAND 是「先认器件、再搬页、再查 ECC、还要躲开坏块」—— 多出来的每一步都是一个独立的失败点,定位时必须按步骤切开看,不能当成一件事。

这份文档解决什么

解决的是样机第一次上电:串口无输出、报 ECC error / bad block / 读超时、或读到空片这一类问题的定位与修复。全文按「差异 → 定段 → 决策树 → 分成因 → 速查 → 清单」组织:第 1 章讲 NAND 与 NOR 在启动这件事上的五条本质差异,第 2 章给出四步手工定位法与抓包断点,第 3 章是决策树,第 4 章是七类根因的原理 + 实操 + 验证,第 5 章是速查表,第 6 章是清单与结案模板。

区分侧重:本文讲样机首次 bring-up(飞线、手焊、转接板、第一次上电、最小系统);产线批量烧录失败、治具供电、烧录器参数卡属于量产篇,两者根因分布不同,不要混用结论。

根因 1
镜像未按页 / 块对齐,OOB 被当数据
页大小、块大小、OOB 大小三方不一致,或者把 OOB 区当成数据区一起搬,ECC 校验码位置对不上。
样机高发:第一次建工程时参数沿用别的项目
根因 2
烧录器跳坏块策略与 BootROM 不一致
烧录器遇到坏块就跳过,后面的数据整体前移;BootROM 按物理块顺序读,读到的块号与期望的镜像块号错开。
样机高发:BOOT 区里恰好有坏块
根因 3
ECC 算法 / OOB 布局不一致
片内 ECC 与软件 ECC 混用、纠错强度不同、校验码在 OOB 里的偏移不同 —— 数据读出来了但校验过不了。
样机高发:换料号后 ECC 参数没跟着改
根因 4
BOOT 区出现坏块且未做重映射
BootROM 只在 BOOT 区的固定 block 里找代码,坏块正好落在这里又没做多副本或重映射,启动必失败。
样机高发:换批次后坏块分布变化
根因 5
上电等待与 OIP 忙等未处理
上电后内部初始化没完成就发命令;或读页后没有轮询状态寄存器的忙标志就取数据,读到的是上一拍的残留。
样机高发:飞线导致上电时序变慢
根因 6
多 die 未选片 / die 间差异
多 die 封装需要先选片;片选命令或地址位数不对时,读的是另一个 die 的内容。
样机高发:换大容量多 die 料号

1. 与 NOR 的本质差异:为什么 NAND 启动难查得多

SPI NOR 与 SPI NAND 都挂在同一个 SPI 控制器上、用几乎一样的引脚,所以很多人下意识把它们当成「同一种东西的不同容量」。但在「启动」这件事上,两者的差别是结构性的:NOR 是给个地址就给你数据,NAND 是一整套带状态、带校验、带坏块管理的存取协议。

1.1 七条必须记住的差异

启动读取的本质差异:同一句「从 Flash 取代码」,NOR 与 NAND 完全不是一回事以 datasheet 与平台手册为准对比项SPI NORSPI NAND访问粒度按字节 / 按地址线性读CPU 可直接取指执行(XIP)按页存取:页大小常见 2 KB / 4 KB(具体数值以 datasheet 为准)地址到数据地址连续线性读哪个地址就是哪个地址的数据地址 = 块号 + 页号 + 页内偏移物理地址与逻辑地址之间有映射坏块基本不存在坏块概念BootROM 不需要处理出厂即存在坏块,使用中还会新增BootROM 必须避开或能处理ECC 校验一般不要求 ECC读出来的字节可直接使用必须有 ECC算法强度与 OOB 布局由三方约定上电可用性上电等待后即可读(等待时间以 datasheet 为准)上电要先等内部初始化完成读页还要等页搬到缓存的延时BootROM 工作量发读命令 → 收数据 → 跳执行一步到位复位 → 读 ID → 读页到缓存 →查坏块 / ECC → 取 SPL,多步失败时表现读到错的字节头校验失败或直接跑飞报 ECC error / bad block / 超时或读到全 0xFF 被判为空片
图 1 · SPI NOR 与 SPI NAND 在启动读取上的本质差异对比

把这张表压缩成三句话,现场就能用:

  • NOR 没有状态,NAND 有状态。NOR 上电就能读;NAND 要先等内部初始化,读页还要等页搬到缓存,每一步都有时间参数(以 datasheet 为准)。
  • NOR 没有坏块,NAND 出厂就有坏块。这意味着「第 N 块」这个说法在 NAND 上是不确定的 —— 同一个逻辑偏移,在不同片子上可能落在不同物理块上。
  • NOR 不需要 ECC,NAND 必须有 ECC。ECC 不是一个开关,而是一整套约定(算法、强度、校验码在 OOB 里的位置),三方必须完全一致。

1.2 BOOT 区:BootROM 只看最前面那几个 block

这是 SPI NAND 启动最核心、也最容易被忽略的概念。BootROM 不可能去跑完整的 NAND 坏块管理与磨损均衡 —— 它的代码量有限,所以绝大多数平台采用「BOOT 区」方案:把器件最前面固定数量的 block(常见说法是前 1 MB 或前若干个 block,具体以平台手册为准)划为 BOOT 区,BootROM 只用最简单的方式(顺序读、有限次重试、或有限的多副本)从这里取 SPL。

由此直接推出三条排查结论:

  1. BOOT 区里的坏块是致命的。后面的块坏了可以靠文件系统或坏块表躲开,BOOT 区坏了 BootROM 没地方可躲 —— 所以要么用平台提供的多副本/重映射机制,要么在烧录时就把 BOOT 区规划在出厂保证无坏块的范围(具体机制以平台手册为准)。
  2. BOOT 区内的烧录策略必须与 BootROM 完全一致。烧录器如果在 BOOT 区里跳坏块,而 BootROM 不跳(或跳法不同),偏移就会逐块累积 —— 这是「烧录成功但不开机」里最难查的一类。
  3. BOOT 区之外的分区错误不会导致不开机。如果 SPL 已经跑起来了、报错在挂载根文件系统阶段,那已经不是 BOOT 区的问题,应该转到驱动/文件系统那一侧排查。
先确认一件事:这颗料号在不在平台的器件支持表里

SPI NAND 不像 NOR 那样「基本都能读」。很多平台的 BootROM 或 SPL 里维护了一张器件支持表(按 JEDEC ID 匹配页大小、块大小、OOB 布局、ECC 参数)。

如果这颗料号不在表里,或者表里的参数与 datasheet 不一致,表现出来的症状和「镜像烧错」一模一样,但根因完全不同。样机阶段换料号、换批次之后突然起不来,第一件事就是核这张表。

2. 分段定位:读 ID → 读页 → 回读比对 → 扫坏块表

NAND 的启动链路比 NOR 长,但相应地可观测点也更多。本章给一套四步手工定位法:先让主控停在能敲命令的地方(U-Boot / 驱动调试层),然后按 ID → 页 → 比对 → 坏块的顺序把问题切开。定段之前不重烧、不换片、不改配置。

2.1 四步手工定位法

# ① 让主控停在 U-Boot / 驱动调试层,先确认能识别到器件
sf probe 0                 # 或平台对应的 nand 命令,以 SDK 为准
nand info                  # 打印页大小 / 块大小 / OOB / 总容量,逐项与 datasheet 核对

# ② 手工读一页并回读比对(地址与长度按页大小换算,以下为示意)
nand read 0x42000000 0x0 0x800
md.b 0x42000000 0x100

# ③ 逐 block 扫描坏块表,重点看 BOOT 区范围内有没有坏块
nand bad                   # 命令名以平台 U-Boot 为准

# ④ 与烧录器侧的读回 dump 做二进制比对
cmp  target_page0.bin  host_page0.bin
md5sum target_page0.bin host_page0.bin

四步各自的判读规则:

步骤期望结果不符合时说明什么下一步
① 读 ID / 打印参数ID 正确;页大小、块大小、OOB 大小与 datasheet 完全一致ID 读不到 → 硬件链路问题;参数不一致 → 器件支持表需要适配该料号修链路 / 补器件表参数
② 读一页并回读读出来的内容与预期内容一致,无 ECC 报错报 ECC error → 第 4 类根因;读到全 0xFF → 该页是空的或该块是坏块核 ECC 参数 / 检查是否真的烧进去了
③ 扫坏块表BOOT 区范围内无坏块;坏块标记位置与平台约定一致BOOT 区有坏块 → 第 4 类根因;标记位置不对 → OOB 布局理解不一致换用多副本/重映射策略,或换片
④ 两边 dump 比对主控读回与烧录器读回二进制一致不一致 → BOOT 区内的跳坏块策略或页对齐不一致统一烧录器与 BootROM 的块映射策略

2.2 逻辑分析仪:抓 BootROM 的命令序列,看断点在哪

串口无输出、或者平台没有可用 BootROM LOG 时,抓包是唯一的手段。抓 SPI NAND 与抓 NOR 的最大区别:NAND 的命令序列更长、中间有「读页到缓存」和「轮询状态寄存器」这两个 NOR 没有的步骤,而恰恰是这两步最容易出问题。

BootROM 从 SPI NAND 取一个标准页的命令序列(命令码以 datasheet 为准)示意,非真实抓包1 上电等待等内部初始化完成时间以 datasheet 为准2 复位 + 读 ID发复位命令,再读JEDEC ID(常见 0x9F)3 发读页命令页地址 → 把整页搬到内部缓存4 轮询 OIP读状态寄存器查OIP 位,等到为 05 读缓存输出读缓存命令 + 列地址+ dummy,然后收数据命令序列断点:抓包停在哪一条 → 死在哪一步 → 首查方向断点(序列停在哪)含义首查方向连复位 / 读 ID 命令都没有出现主控没发命令或链路根本不通查 VCC/VCCQ、复位脚查 CS#/CLK 波形与片选读 ID 返回全 0x00或全 0xFF器件没有响应多为焊接 / 供电问题查焊接、CS# 上拉查 IO 电压域是否匹配ID 正确,但后面没有读页命令BootROM 不认这个 ID或器件表无该料号查平台器件表确认是否需要适配有读页命令,但没有轮询 OIPBootROM 用固定延时而非轮询状态寄存器核延时是否覆盖该料号最坏情况读命令与轮询都在,但读回的数据不对ECC 失败 / 坏块 /页对齐错核 ECC 与 OOB 布局扫描坏块、核页大小
图 2 · BootROM 读 SPI NAND 的命令序列与抓包断点对照

抓包的三条实操要点:

  • 探头要够。除了 CS#、CLK、DI(IO0)、DO(IO1),Quad 模式还要接 IO2、IO3;多 die 器件必要时还要看片选相关的信号。
  • 解码要分两段。读 ID 阶段通常是单线,读缓存输出阶段可能已经切到 Quad。用同一套解码参数解全程会解出乱码,先按单线解到读 ID,再按抓到的读命令码判断后面该按几条线解。
  • 重点看 OIP 轮询有没有出现、出现了几次。如果 BootROM 发完读页命令后没有轮询就直接取数据,说明它用的是固定延时 —— 那就要核这个延时是否覆盖该料号的最坏情况(以 datasheet 为准)。
危险操作:NAND 排查中的高危动作

① 禁止用 SPI NOR 的算法/工程烧 SPI NAND。NAND 需要页编程 + ECC + 坏块管理,用 NOR 的裸写方式会「假成功」—— verify 通过但主控读不出来,而且会破坏 OOB 里的 ECC 与坏块标记。

② 禁止在定段之前反复擦除重烧。NAND 的擦除次数有限,更重要的是每擦一次坏块表和 OOB 标记就可能变一次,故障变得不可复现。

③ 禁止手动改写 OOB 区。OOB 里的坏块标记一旦被写坏,好块会被当成坏块(或反过来),整个器件的块映射全乱,这种情况下只能整片重新规划,数据不可恢复。

④ 禁止带电补焊 / 飞线。与 NOR 同理,但 NAND 的页缓冲区在掉电瞬间更容易被写到一半,风险更高。

3. 决策树:从上电现象到根因类目

把第 2 章的四步定位固化成一张图:两个判据、四条出口,每条出口直接指向一个根因类目和该段的首查动作。NAND 的决策树比 NOR 更依赖「读 ID 是否成功」这个分水岭 —— 因为 NAND 的器件识别本身就包含了参数协商。

SPI NAND 上电:无 LOG / 报 ECC 或坏块错Q1 串口有输出 / 能读到 ID 吗?否第 1~2 段 硬件与识别判据:无输出 / ID 读不到查 VCC/VCCQ 与复位脚抓 CS#/CLK 看有无命令是Q2 BootROM 报什么错 / 停在哪?第 3 段 BOOT 区坏块判据:bad block / 全 0xFF扫描 BOOT 区坏块表重映射到预留块 / 多副本第 4 段 ECC 不一致判据:ECC error核对算法强度与 OOB 布局核对片内 / 软件 ECC 选择第 5 段 时序与选片判据:读超时 / 卡死核上电等待与 OIP 轮询核多 die 片选与页对齐NAND 铁律:BootROM 只认 BOOT 区里固定数量的 block,按物理顺序读烧录器跳过的坏块会让它后面的数据整体前移,BootROM 顺序读到的就全错位了
图 3 · SPI NAND 首次启动失败决策树

3.1 走树时的四条纪律

  • 先确认参数,再确认数据。ID / 页大小 / 块大小 / OOB 大小只要有任一项与 datasheet 不符,后面所有的数据比对都没有意义。
  • 每条分支都要留下物证。走完树不能只说「我核过 ECC」,要留下 ECC 配置值、抓包文件、坏块表输出、比对文件的 md5。
  • 一次只改一个变量。ECC 参数、坏块策略、页对齐三个一起改,就算通了也不知道是哪一个生效的,下次还会复发。
  • 换片对比是有效的判据。换一颗同料号新片:如果好了,说明是这颗片子的坏块分布问题(第 4 类根因);如果还是一样,说明是配置或板级问题 —— 但换片之前必须先把原片的坏块表导出来,否则证据就丢了。
关于「偶发」的处理

NAND 的偶发失败比 NOR 更常见,因为坏块和 ECC 都带随机性。做法与 NOR 相同:连续 50~100 次上电,记录每次的停点与报错码。

额外加一步:记录每次失败时报错的块号/页号。如果失败集中在固定的几个块,几乎可以确定是坏块或其邻块的读干扰问题;如果块号随机,优先怀疑上电时序与 OIP 等待(第 5 类根因)。

4. 分成因排查:七类根因的原理、实操与验证

七个根因按样机首次 bring-up 的出现概率排序。每一条按原理 → 实操 → 验证三段给,「验证」是判断是否真的解决了的标准。

4.1 根因 1:镜像未按页 / 块对齐,OOB 被当成数据

原理。NAND 的最小写入单位是页、最小擦除单位是块,而且每页后面跟一段 OOB(spare)区。镜像是按「连续数据流」组织的,而 NAND 是按「页 + OOB」组织的 —— 这两者之间必须有一个明确的映射规则。

三种典型的对齐错误:

  • 页大小不一致:烧录器按 2 KB 页算偏移,器件实际是 4 KB 页,每一页的起点都错。
  • OOB 被当成数据搬:把 OOB 区的内容一起读到数据缓冲区里,或者把数据写进了 OOB —— ECC 校验码的位置全乱。
  • 块边界没对齐:一个逻辑分区的起点落在块的中间,擦除时把前一个分区的尾巴一起擦掉。
① 单页布局:数据区 + OOB(spare)区,两者都不能理解错数值以 datasheet 为准数据区(page size,常见 2 KB / 4 KB,以 datasheet 为准)OOB / spare 区ECC 校验码 + 坏块标记OOB 区不是数据区:把 OOB 当数据读进来,或者把数据写进 OOB,都会让 ECC 对不上一块 = 若干页(常见 64 / 128 页,以 datasheet 为准);擦除按块,读写按页② 坏块跳过导致的偏移累积:烧录器视角 vs BootROM 视角物理块好坏分布B0 好B1 坏块B2 好B3 好B4 好烧录器跳坏块写镜像块 0(跳过)镜像块 1镜像块 2镜像块 3BootROM按块顺序读读块 0 对读块 1 坏块读块 2 错位读块 3 错位读块 4 错位结论:BOOT 区必须选在出厂保证无坏块的范围,或采用平台支持的多副本 / 重映射策略烧录器的跳坏块策略必须与 BootROM 的读取策略完全一致,否则偏移会逐块累积
图 4 · 页 / 块 / OOB 布局与坏块跳过导致的偏移累积示意

实操。

  1. 把三方的参数抄到一张纸上对照:datasheet 的值、烧录工程里的值、主控侧 nand info/驱动打印出来的值。三方必须完全一致。
  2. 确认烧录器的「是否包含 OOB」「spare 区处理方式」这一项设置,与平台期望的方式一致(有的平台要求 ECC 由烧录器算好写进 OOB,有的要求烧录器只写数据区、ECC 由主控算 —— 以平台手册为准)。
  3. 手工读一页,把数据区和 OOB 分别 dump 出来,确认数据区是镜像内容、OOB 里是 ECC 校验码而不是镜像数据。

验证。三方参数完全一致;手工读页与预期内容二进制一致;OOB 的内容和布局与平台约定一致。

4.2 根因 2:烧录器跳坏块策略与 BootROM 不一致

原理。这是 NAND 独有、也是最隐蔽的一类根因。烧录器写镜像时,遇到坏块会跳过去,把后续数据写到下一个好块,这样「逻辑上连续的镜像」在物理上就是「跳过坏块的非连续布局」。而 BootROM 的读取策略是另一套:它可能按物理块顺序读、也可能自己跳坏块,但跳转规则未必与烧录器一致(具体以平台手册为准)。

后果是偏移逐块累积:BOOT 区里只要有 1 个坏块,它后面的所有块号就整体错开 1 个;有 2 个就错开 2 个。BootROM 读「第 N 块」时期望的是镜像的第 N 块,实际读到的是第 N+k 块的内容 —— 数据本身是正确的,只是位置全错了。

实操。

  1. 先导出整片的坏块表,看 BOOT 区范围内(具体范围以平台手册为准)有没有坏块。
  2. 查烧录工程的「坏块处理策略」:跳过 / 保留 / 替换为预留块,与平台 BootROM 的期望策略对照。
  3. 如果平台提供多副本或重映射机制,确认烧录时确实生成了副本 / 写入了重映射表。
  4. 在 BOOT 区范围内逐块读出块首的标记,人工核对「第 N 个物理块里装的是不是镜像的第 N 块」。

验证。BOOT 区内逐块核对通过(物理块序与镜像块序一一对应),或平台的多副本/重映射机制已确认生效且上电连续 100 次都能起来。

最容易踩的坑:BOOT 区策略与数据区策略要分开看

很多平台的做法是:BOOT 区用「固定块 + 多副本」的简单策略,数据区才用完整的坏块管理。原因是 BootROM 跑不了复杂算法。

所以「烧录器的坏块策略」往往不是全局一个开关,而是分区各自配置。只改了全局开关、没改 BOOT 区的策略,症状就是「数据区都对了、就是起不来」。

4.3 根因 3:ECC 算法 / OOB 布局不一致

原理。NAND 的位翻转是物理特性,必须靠 ECC 纠正。ECC 不是「开或关」,而是一整套约定:用哪种算法(BCH / RS 一类)、能纠几位、校验码占多少字节、放在 OOB 的哪个偏移、覆盖的数据范围是整页还是分段。

典型的三方不一致:

不一致的点具体表现后果
片内 ECC vs 软件 ECC 混用器件内部自带 ECC 引擎,烧录器又按软件 ECC 算了一遍写进 OOB两套校验码互相干扰,主控读出时校验必然失败
纠错强度不同烧录器按纠 4 位算,主控按纠 8 位解校验码长度与位置都对不上,报 ECC error
OOB 内偏移不同校验码写在 OOB 起始处 vs 写在 OOB 中间数据区内容是对的,但主控找不到校验码
覆盖的数据范围不同整页一个校验块 vs 每 512 字节一个校验块部分数据能过校验、部分不能,症状看起来像随机坏块

实操。

  1. 确认该料号是片内 ECC 还是需要外部 ECC(以 datasheet 为准);如果是片内 ECC,主控侧就不要再算一遍。
  2. 确认平台 SDK 里配的 ECC 强度与 OOB 布局,与烧录工程里配的逐项对照 —— 包括校验码长度、偏移、覆盖粒度。
  3. 手工读一页,把 OOB 的十六进制打出来,人工数一遍校验码的起始偏移与长度,验证与配置一致。

验证。手工读页不再报 ECC error;连续读 BOOT 区所有页 100 次,无一次校验失败。

4.4 根因 4:BOOT 区出现坏块且未做重映射

原理。如 1.2 节所述,BootROM 只在 BOOT 区的固定 block 里找代码。boot 区里的坏块是致命的,因为 BootROM 没有复杂的坏块管理可以躲。

样机阶段高发的场景:同一料号换了一个批次,坏块分布变了 —— 上一批的 BOOT 区全是好块,这一批的第 2 个 block 就是坏块,于是「同样的工程、同样的操作,换批就不开机」。

实操。

  1. 导出完整坏块表,标出 BOOT 区范围内所有坏块的块号。
  2. 查平台手册确认该平台对 BOOT 区坏块的处理机制:多副本(把 SPL 烧在多个固定块、BootROM 逐个试)/ 重映射表(把坏块映射到预留的好块)/ 出厂保证前 N 块无坏块。
  3. 按平台要求重新生成镜像与烧录配置:副本数、副本块号、重映射表位置,都必须严格按手册来。
  4. 如果平台机制要求「BOOT 区必须在出厂保证无坏块的范围」,就把 BOOT 区规划到更小的范围(以平台手册为准)。

验证。在多颗不同批次的片子上(至少 3 颗,含已知 BOOT 区有坏块的)连续上电 100 次,全部能起来。

4.5 根因 5:上电等待与 OIP 忙等未处理

原理。NAND 上电后需要内部初始化(上电复位时间一类的参数,以 datasheet 为准),之后才能接受命令;发出「读页到缓存」命令后,还要等器件把整页搬到缓存,这段时间由状态寄存器里的忙标志(常见叫 OIP / BUSY)指示。

两类典型故障:

  • 上电等待不足:主控在器件还没初始化完就发命令,器件不响应,读 ID 返回全 0x00 或全 0xFF。样机上如果电源爬升慢、或者复位释放太早,这一类会偶发。
  • 发完读页命令没有轮询忙标志:主控用固定延时代替轮询,延时不够时读到的是上一次的残留数据或全 0xFF;延时够但没轮询,则在温度升高、器件变慢时失效。

实操。

  1. 示波器抓上电瞬间 VCC 与复位脚,确认从 VCC 稳定到第一个 CS# 下降沿的时间,不小于 datasheet 要求的上电等待时间。
  2. 抓包确认 BootROM 在读页命令之后有没有轮询状态寄存器;如果没有,说明它用固定延时 —— 记录这个延时的实测值。
  3. 把实测延时与该料号 datasheet 里「读页到缓存」的最坏时间对比,不足则需要平台侧调整(以平台手册为准,不要自行改 BootROM)。
  4. 高低温拉偏:在最恶劣温度下重复上电,确认没有因器件变慢而读错。

验证。在全温度范围内、电源在最慢爬升条件下,连续上电 100 次全部成功启动。

4.6 根因 6:多 die 未选片 / die 间差异

原理。大容量的 SPI NAND 常把多个 die 封装在一起。访问不同 die 需要先发选片命令(或地址里带 die 位),没选片或选错片,读出来的是另一个 die 的内容 —— 内容合法、ECC 也可能对,但完全不是你要的那个地址的数据。

实操。

  1. 从 datasheet 确认该料号是单 die 还是多 die,以及选片的方式(专用选片命令 / 地址高位 / 其它,以 datasheet 为准)。
  2. 抓包看 BootROM 在跨 die 边界访问时有没有发选片命令;如果 BOOT 区跨了 die 边界而没有选片,这就是根因。
  3. 如果平台器件表支持该料号,确认表里的 die 相关参数正确;不支持则需要适配。
  4. 规避方案:在平台允许的前提下,把 BOOT 区规划在第一个 die 之内,避免 BootROM 阶段跨 die 访问。

验证。在 die 边界两侧各读写一组 pattern,回读确认读到的就是写进去的内容,没有串到另一个 die。

4.7 根因 7:样机专属 —— 飞线、转接板、手焊

原理。与 NOR 一样,这一类只会在样机阶段出现。但 NAND 对它的敏感度更高:NAND 的读页涉及「命令 → 长延时 → 读输出」多个阶段,中间任何一次信号完整性问题都会让整个页读失败,而且失败表现为 ECC error,很容易被误判成 ECC 配置问题。

样机特有做法引入的问题排查 / 规避动作
飞线过长(>10 cm)CLK 边沿变缓,命令相位采样错误,表现为随机 ECC error尽量缩短;CLK 串联阻尼电阻;先降到最低频率验证
CLK 与 DI/DO 并行长距离走线串扰导致命令码本身被读错,抓包看到的是「奇怪的命令」信号之间插地线;或把 CLK 单独走、远离数据线
转接板 / 烧录座没有地回流路径回流面积大,Quad 读时 DO 上的毛刺被当成数据转接板上铺地、多打地过孔;用尽量短的排线
手工焊接虚焊 / 助焊剂残留接触电阻大,表现为「时好时坏」,与坏块/ECC 故障很难区分显微镜下复检;清洗助焊剂;先排除它再查 ECC
多颗器件共用一套飞线片选隔离没做好,总线上有两个驱动源确认未选中的器件处于高阻;必要时只焊一颗做最小系统
最小系统法:把变量一次性砍到最少

当怀疑是样机板级问题时,按这个顺序砍变量:

① 只焊一颗 SPI NAND,去掉板上所有其它外设;② 用最短的线、直连而不是飞线;③ SPI 时钟降到最低、强制单线模式;④ 烧最小可启动镜像(只要 SPL 能打印即可)。

四步做完能起来,再逐项把变量加回来,每加一项上电验证一次。这一步能把「板级 / 参数配置 / 镜像布局」三类问题干净地分开,比在完整系统上猜要快得多。