只读分享解决方案文档原理方案设计📅 2026-10-05🔖 V1.2✅ 长期有效
🔧解决方案&应用市场分析 -> 原理方案设计 -> 并行总线系列产品方案 -> 并行NAND_PPI_NAND_软件设计规范

并行NAND_PPI_NAND_软件设计规范

生成时间 2026-09-21 11:12:12 长期有效
同系列 · 原理方案设计

PPI NAND Flash 软件设计规范

编制日期 2026-10-05 | 版本号 Rev 1.4

PPI-NAND-SW-SPEC-001 · V1.2
面向嵌入式系统 PPI NAND(并行接口 / Parallel NAND,含 ONFI Async、NV-DDR、Toggle)驱动、BBM/FTL 与中间件的设计约束与推荐实现。阵列语义与《SPI NAND》对齐,差异集中在并行总线接口、命令组帧与 HAL 职责边界。

18章节
11附录
8-bitECC 默认
R/B#+SR双重确认
文档编号PPI-NAND-SW-SPEC-001
版本V1.2
状态正式发布
适用范围嵌入式系统 PPI NAND(并行接口 / Parallel NAND,含 ONFI Async、ONFI NV-DDR、Toggle 等)驱动、BBM/FTL 与中间件
参考标准ONFI(Open NAND Flash Interface)、厂商 Datasheet、Linux MTD nand / onenand 实践、JEDEC 并行 NAND 惯例
配套文档《SPI NOR》《SPI NAND》《SD NAND》《eMMC》软件设计规范

1. 目的与范围

本规范规定 PPI NAND(Parallel Peripheral Interface NAND,即传统 并行接口裸 NAND)软件层的设计约束与推荐实现,目标是:

  • 正确实现 CLE / ALE / CE# / WE# / RE# / R/B#(及可选 DQS)时序下的命令、地址、数据周期
  • 规范 HAL / NFC 控制器 与驱动的职责边界(时序寄存器、位宽、EDMA、ECC 引擎)
  • 保证读/编/擦可靠性(超时、R/B# + Status 双重确认、Fail 位、掉电安全)
  • 正确处理 坏块管理(BBM)、片上/主机 ECC(含 8-bit 下 ≥6 bit 迁块标坏)、OOB/Spare
  • 落实 整页一次写入 与 Partial Page Program 次数限制(默认 ≤4)、块内顺序编程、擦后 Blank Check
  • 控制物理擦写次数(软件防抖 / 磨损均衡 / 读干扰 scrub / FTL)
  • 规范使用 ONFI Parameter Page、Read ID、UID、OTP、WP# / 分区锁、Cache、多 Plane 等能力
  • 落实 SDR 保底与 NV-DDR/Toggle 防变砖、替换池耗尽降级、Boot 非 XIP
  • 规范 PPI NAND 与文件系统 的分层选型、分区(重要性/频率隔离)、挂载与掉电策略

与 SPI NOR / SPI NAND / SD NAND 的本质差异(必须理解):

维度 SPI NOR SPI NAND PPI NAND SD NAND
主机视角 SPI 字节命令 SPI 页 Cache 命令 并行总线命令周期(CLE/ALE) SD 块设备
坏块 / ECC 通常无 / 可选 主机 BBM + ECC 主机 BBM + ECC(同裸 NAND) 片内 FTL 完成
忙判定 WIP(05h) Feature C0h OIP R/B# 引脚 + Status 70h DAT0 Busy / 令牌
发现参数 SFDP Feature + Param Page ONFI Parameter Page / ID 表 CID/CSD
接口 SPI/QSPI SPI/QSPI 8/16-bit IO + 控制线 SD/SPI
文件系统 可直挂友好 FS 禁裸挂 FatFS 禁裸挂 FatFS(同 SPI NAND) 可挂 FatFS

PPI NAND 与 SPI NAND 在阵列语义上高度一致(页编程、块擦除、坏块、ECC、FTL);差异几乎全在 主机接口与命令组帧。本规范 BBM / ECC / FS 策略对齐《SPI NAND》,接口与 HAL 章节按并行总线展开。

不在本规范范围: PCB 走线与 DDR/Toggle 电气完整性细则、具体厂商扩展命令全表(以 Datasheet 为准)、完整 FTL 算法论文级细节、某一 SoC NFC 寄存器手册全文。

2. 术语与缩写

术语 说明
PPI NAND Parallel Peripheral Interface NAND;并行接口裸 NAND(相对 SPI NAND)
CLE / ALE Command Latch Enable / Address Latch Enable;锁存命令或地址
CE# / WE# / RE# Chip Enable / Write Enable / Read Enable(低有效惯例)
R/B# Ready/Busy#;忙时拉低,完成后释放为高(开漏常见,需上拉)
I/Ox 双向数据总线;常见 ×8 或 ×16
DQS 源同步数据选通(NV-DDR / Toggle 模式)
SDR / Async 异步单数据速率接口(经典并行 NAND,本规范默认)
NV-DDR / Toggle ONFI / Toggle 源同步高速模式
NFC / EBI / FSMC SoC 侧并行 NAND / 外部总线控制器(名称因芯片而异)
Page 编程最小单位;常见 2KB+64B、4KB+128/218/224B 等(含 OOB)
Block 擦除最小单位;常见 64/128/256 页
Plane / LUN / Die / Target 多平面/逻辑单元/Die/目标片选;影响并行与 CE# 选择
Column / Row 页内字节偏移 / 页号(含 Block+Page,多 Plane 含平面位)
OOB / Spare 页外带区;ECC、坏块标记、FTL 元数据
Status Register 读状态命令(常 70h)返回的 SR;含 Ready、Fail、WP 等
Fail Program Fail / Erase Fail 状态位(命名因厂而异)
ONFI Open NAND Flash Interface
Parameter Page ONFI 参数页(几何、时序、特性、CRC)
ECC 强度 每码字可纠正最大比特数;本规范默认示例 8-bit
位翻转阈值 可纠正错误达阈值时迁块;默认 8-bit 下 ≥6 bit
PPP Partial Page Program,同一物理页在两次 Erase 之间的部分编程次数
BBM Bad Block Management
FBBT Factory Bad Block Table;由扫描 OOB 工厂标记生成
BB Marker 坏块标记:通常为 Block 内指定页 Spare 首字节非 0xFF
初始坏块率 出厂允许坏块比例,行业常见上限约 2% 总块数
FTL / NFTL Flash Translation Layer;向通用 FS 提供块设备抽象
LBA Logical Block Address
GC Garbage Collection
tCLS/tCLH/tALS/tALH 命令/地址建立与保持时间
tWP / tWH / tRP / tREH WE#/RE# 脉冲宽度与高电平时间
tWB / tR / tPROG / tBERS / tRST 命令后忙、读阵列、编程、擦除、复位时间
tVSL / tPOR 上电到允许命令的等待时间
WP# Write Protect 引脚;硬件写保护
Cache Read / Program 页缓冲流水命令,用于吞吐优化
Copyback 片内页搬移;默认禁止作用户迁移主路径

容量与几何换算约定:

  • 软件内部统一用 字节逻辑地址 或 (target, lun, plane, block, page, column);驱动层必须能互转
  • 禁止把 PPI NAND 当成“按 4KB Sector 擦的 NOR”或“SD 块设备”来建模
  • 禁止把 SPI NAND 的 13h/0Fh Feature 帧直接套到 PPI 总线上
  • ×16 器件:能力表必须写明 Column 与主机缓冲是按 字节 还是按 字 计数
应用 / 文件系统UBIFS / LittleFS+FTL · 日志与 OTAFTL / 磨损均衡 / 逻辑卷逻辑块映射 · GC · 寿命管理BBM(坏块管理)坏块表 · 替换池 · 标坏 / 搬移PPI NAND 驱动命令序列 · ECC 判读 · 超时 · ONFIHAL(周期原语)CLE/ALE 命令 · 地址 · 数据 · R/B# · 硬件 ECC并行 NAND 控制器FSMC / EBI / NFC / GPIO bitbang
图 1 · PPI NAND 软件分层架构:BBM / ECC 决策与 SPI NAND 同层,差异集中在 HAL 与总线接口

3. 软件分层架构(推荐) 推荐

┌──────────────────────────────────────────────┐
│  应用 / 文件系统 (UBIFS / LittleFS+FTL...)   │
├──────────────────────────────────────────────┤
│  FTL / 磨损均衡 / 逻辑卷                     │
├──────────────────────────────────────────────┤
│  BBM(坏块表、替换、标记)                    │
├──────────────────────────────────────────────┤
│  PPI NAND 驱动(命令序列、ECC、超时、ONFI)  │
├──────────────────────────────────────────────┤
│  HAL:周期原语 + 时序/位宽/DMA/硬件 ECC      │
├──────────────────────────────────────────────┤
│  并行 NAND 控制器(FSMC/EBI/NFC/GPIO bitbang)│
└──────────────────────────────────────────────┘

强制要求:

  1. 应用层禁止直接拨 CLE/ALE 发 Erase / Program;必须经驱动统一入口。
  2. 坏块判定与替换不得散落在业务代码;统一由 BBM 层处理。
  3. HAL 只提供:发命令 / 发地址 / 写数据 / 读数据 / 读 R/B# / 可选硬件 ECC 结果;不得在 HAL 内散落业务超时策略。
  4. 驱动初始化必须完成:
  5. 等待 tVSL → Reset(FFh)→ 等 R/B# → Read ID → 读 ONFI Parameter Page / 静态几何表 →
  6. 配置时序/位宽/ECC → 扫描/加载坏块表 →(可选)挂载 FTL。
  7. 同一颗料的 SDR / DDR / Toggle 模式切换必须有能力表与恢复路径;禁止未验证就开高速模式。

VCC↑ → 等待 tVSL → Reset → 等 R/B# → 探测几何 → 配置 → 加载 BBTtVSL电源好≥Max tVSLFFhSoft ResetR/B#忙窗口释放90hRead IDParamONFI 参数页/静态表CFG时序/位宽/ECCBBT扫描/加载坏块表禁止项① 不等 tVSL 就发 90h/70h/FFh —— ID 全 0x00/0xFF、R/B# 假 Ready、状态机卡死② 跳过 R/B# 等待 —— 复位未完成即读 ID,结果不可信③ 未验证就开 NV-DDR / Toggle 高速模式(需能力表 + 恢复路径)
图 2 · 上电初始化七步:tVSL 等待是并行总线特有的强制前置,远重于 MCU 复位释放
3.1 上电时序 tVSL(强制) 强制

VCC 到达工作电压后,PPI NAND 不能立刻接收命令。Datasheet 规定的 tVSL / tPOR(厂商命名不一)未满足时发 90h/70h/FFh 等,可能导致:ID 全 0x00/0xFF、R/B# 假 Ready、擦写进入不确定态,甚至把控制器时序状态机卡死在错误模式。并行总线比 SPI 更依赖电源稳定——IO 上拉、CE# 默认态、R/B# 开漏在上电斜坡期间都可能处于中间电平。

项 要求
等待起点 以“电源好 / 电压监控释放 / ADC 确认 VCC≥VCC(min)”为起点,而非仅以 MCU 复位释放为起点
等待时间 ≥ 目标器件 Datasheet Max tVSL / tPOR;多料号兼容时取清单内最大值
典型量级 常见数十 µs ~ 数 ms(以 Datasheet 为准;禁止凭经验写死过小值)
与 BOR 关系 Brown-out 恢复后视为重新上电,必须重新等待 tVSL,并强制回 SDR 安全时序
首条命令 tVSL 满足前:禁止 Read ID / Status / Parameter Page / 擦写 / 切 DDR
Soft Reset FFh 后须满足 tRST 并等 R/B# Ready(双重确认),再发其它命令
R/B# 上拉 开漏必须有合适上拉;上电初期高阻/毛刺不得判为 Ready——以 Status 为准
实现位置 建议在 ppi_nand_init() 最前部统一等待,避免各调用点遗漏
wait_until_vcc_ok()
delay_at_least(tVSL_max)
hal_set_bus_sdr_safe()           // 控制器回异步安全时序
nand_reset()                     // CLE: FFh
wait_rb_ready_double()           // R/B# 或 Status Ready,双重确认
id = read_id()                   // CLE: 90h + ALE + 读 ID
param = read_parameter_page()    // ECh 等
configure_timing_ecc_wp()
scan_or_load_bbt()

3.2 Boot / 启动架构(强制) 强制

PPI NAND 通常不支持像 SPI NOR 那样的 CPU Memory-Map XIP 直接取指启动(部分 SoC 的 NFC BootROM 属专项认证例外)。

项 要求
启动介质 BootROM / 片内 ROM / 小容量 SPI NOR / eMMC 等可执行介质加载一级 Loader
NAND 角色 存放 App、文件系统、资源;由 Loader/App 通过命令模式访问
禁止 假定把 NAND 映射到地址空间即可执行代码(除非芯片与料号明确支持且已专项认证)
双 Flash 推荐:NOR 存 Bootloader + 关键恢复镜像;PPI NAND 存大容量数据
恢复 NAND BBT/FTL 损坏时,仍须能从 NOR/ROM 进入维护模式重刷
Loader 接口 Loader 必须能在 Async SDR 下完成 Reset / ID / 基本页读
Power-On → ROM/NOR 启动 Loader
        → 初始化 PPI NAND 驱动(§3.1)
        → 加载 BBT / 挂载 FTL
        → 校验并跳转 App(代码先拷入 RAM,或按平台支持方式加载)

3.3 HAL 原语与职责边界(强制) 强制

HAL 原语(示例) 职责
cmd(uint8_t c) CLE=1, ALE=0,写入命令字节,满足 tCLS/tCLH/tWP
addr(uint8_t *a, n) CLE=0, ALE=1,写入 n 个地址字节
write_data(buf, n) CLE=0, ALE=0,WE# 写入数据
read_data(buf, n) CLE=0, ALE=0,RE# 读出数据
rb_is_busy() 采样 R/B#(注意开漏与毛刺)
ecc_hw_* 可选:启动/取回硬件 ECC 结果
项 要求
禁止 HAL 内写死某料号的“擦完延时 3ms 就返回成功”
禁止 业务层直接操作 NFC 寄存器绕过驱动锁
EDMA DMA 完成 ≠ 阵列操作完成;仍须 Ready 双重确认
中断 R/B# 边沿中断可唤醒轮询,不可单独作为成功依据

3.4 控制器时序配置(强烈推荐) 强烈推荐

软件必须在能力表/设备树中配置(名称因 SoC 而异),并与 Datasheet 全温最差取交:

参数类 示例 说明
命令/地址 tCLS, tCLH, tALS, tALH, tCS, tCH 建立/保持
写脉冲 tWP, tWH, tDS, tDH 数据建立相对 WE#
读脉冲 tRP, tREH, tREA, tRHZ 数据有效窗
模式 SDR / DDR / Toggle、DQS 延迟 高速模式专项
位宽 ×8 / ×16 与料号一致

配错 tREA/tRP 的典型症状:读数据偶发错位、ECC 误报升高、ID 字节漂移。量产前必须在高低温下抽测。

4. 读 / 编 / 擦操作与 Timeout(强制) 强制

同一语义(读页)在两种接口上的组帧差异PPI NAND(并行总线)CLE↑ 发 00h(Read)ALE↑ 发 列地址 ×2ALE↑ 发 行地址 ×3~5R/B# 忙窗口(阵列读)CLE↑ 发 30h(确认)RE# 沿读 I/Ox 数据SPI NAND(SPI 命令帧)06h WREN13h Page Read to Cache0Fh 轮询 OIP(C0H)03h/0Bh 读 Cache(无 CLE/ALE 概念)SO/SI 串行位移语义相同 组帧不同
图 3 · 命令模型对照:SPI NAND 的 13h/0Fh Feature 帧严禁套到 PPI 总线上
4.1 命令模型(与 SPI NAND 对照)

PPI NAND 通过 命令周期 + 地址周期 + 数据周期 访问阵列,不是 SPI 单帧 Opcode。

4.1.1 读页(Page Read)— 典型 ONFI / 传统序列

1. CLE: 00h
2. ALE: Column(通常 2 字节)+ Row(通常 3 字节)  // 以 Datasheet 为准
3. CLE: 30h
4. 等待 tWB 后轮询 R/B# → Ready(双重确认);或读 Status Ready
5. 检查 / 准备 ECC(On-Die 状态或主机解码)
6. (可选)CLE: 05h(2 周期列地址)→ E0h 随机数据输出(Random Data Output)→ RE# 突发读出 Main/OOB
7. 主机侧处理 OOB / 软件 ECC(若未用 On-Die / 硬件 ECC)

4.1.2 Random Data Output(页内随机读出)

1. 已完成 00h-30h 且 Ready
2. CLE: 05h
3. ALE: Column
4. CLE: E0h
5. RE# 读出从 Column 起的数据

用途:只读 OOB、只读某 ECC step、BBT 扫描。禁止用错误 Column 宽度导致读飞。

4.1.3 编程(Page Program)

1. CLE: 80h
2. ALE: Column + Row
3. 写入 Main [+ OOB] 数据(WE# 周期;主机 ECC 则先编码)
4. CLE: 10h
5. 等待 R/B# Ready(双重确认)
6. CLE: 70h 读 Status;检查 Fail;失败则按坏块策略处理

4.1.4 Random Data Input(页内随机写入)

CLE: 85h + ALE Column + 写数据

仍计入 PPP;与 Main 同一次 10h 提交前的多次 85h 也计入次数(以 Datasheet 为准)。

4.1.5 擦除(Block Erase)

1. CLE: 60h
2. ALE: Row(指向块内约定页,通常首页)
3. CLE: D0h
4. 等待 R/B# Ready(双重确认)
5. Status 检查 Erase Fail;失败则标记坏块

多 Plane 擦除(若启用):按 Datasheet 使用 60h-60h-D0h 等变体;默认产品路径关闭。

4.2 与 SPI NAND 命令映射(防混用速查)

操作 SPI NAND(典型) PPI NAND(典型)
页读到阵列完成 13h + 轮询 C0h OIP 00h…30h + 等 R/B#
从页缓冲读出 03h/0Bh… RE# 读数据 / 05h-E0h
编程 06h+Load+10h 80h+data+10h
擦除 06h+D8h 60h+D0h
读状态 Get Feature 0Fh+C0h 70h Status
读 ID 9Fh 90h
Reset FFh / 66h+99h FFh
参数页 Feature OTP + Page Read ECh Read Parameter Page
配置 Set Feature 1Fh ONFI EFh/EEh(若支持)

4.3 基本原则

并行 NAND 的“操作完成”由阵列内部状态决定,主机无法从“发完命令”推断结果。噪声、假 Ready、掉电半完成都会让“盲延时成功返回”变成静默坏数据。

强制规则:

  1. 所有 Page Read(阵列搬移)/ Program / Block Erase 必须:
  2. 按 Datasheet 发送完整命令/地址/数据周期(CLE/ALE/数据节拍不得缺周期)
  3. 等待 R/B# Ready,并用 Status 双重确认(见 §4.5;本规范唯一合法完成模板)
  4. 同时施加 分类 Timeout(读 / 编 / 擦 / Reset 分表,禁止万能超时)
  5. 完成后检查 Fail / ECC status;Fail 或不可纠正 ECC 不得当成功
  6. 禁止仅靠固定 delay_ms() 盲等;轮询为主,Timeout 为辅。
  7. Timeout 到期后:禁止假定成功;应读 Status、必要时 Soft Reset(FFh)并回 SDR,返回可区分错误码。
  8. 禁止在 R/B# 忙期间发起无关命令(除 Datasheet 允许的 Read Status 70h)。
  9. 禁止在未持驱动锁时穿插另一任务的 CLE/ALE 序列(总线被打断等价于命令损坏)。
  10. Program/Erase 前确认目标块不在坏块表;读路径也须拒绝对已知坏块的“当好块用”。

4.4 Timeout 取值策略

Timeout 过短 → 正常慢擦被当成失败并误标坏块;Timeout 过长 → 真卡死拖死整机看门狗。并行 NAND 的 tR / tPROG / tBERS 随工艺、温度、循环次数变化大,必须按料号分类配置。

优先级 方法 说明
1 Datasheet Max tR / tPROG / tBERS / tRST 最大值 + 20%~50% 余量
2 Parameter Page 若提供典型/最大时间字段则优先解析并交叉核对 Datasheet
3 产品配置表 按 Read ID / ONFI 签名查本地能力表(兼容无有效 Parameter 的料)

推荐默认量级(仅参考,必须以料号为准):

操作 典型量级 软件 Timeout 建议
Page Read(tR) 20 ~ 100 µs Max × 1.5,且 ≥ 1 ms
Page Program(tPROG) 0.3 ~ 3 ms Max × 1.5,且 ≥ 10 ms
Block Erase(tBERS) 2 ~ 15 ms(SLC)~ 更长(MLC/TLC) Max × 1.5,且 ≥ 50~100 ms
Soft Reset(tRST) 按 Datasheet Max + 余量;单独配置
Cache 相关 按 Datasheet 单独配置,禁止复用 tR/tPROG
命令后进忙(tWB) 数十~数百 ns 量级 轮询前可插入极短等待,但不得替代 Ready 判定

禁止与 SPI NOR 共用 Sector/Chip Erase 超时表;禁止与 SPI NAND 共用“只轮询 Feature、不接 R/B#”的实现;禁止全项目一个“万能 5 秒超时”。

高温、接近寿命末端时 tPROG/tBERS 可能显著变长:能力表可提供 timeout_hot_scale(例如 ×1.2),与 §7.5 温度策略联动。

命令发出后:先等 R/B# 释放,再读 Status 判定 Fail/OIP80h+地址10h 执行阵列操作进行中R/B# 拉低(忙)R/B#↑ 就绪R/B# 引脚忙窗口(tPROG / tBERS)R/B# 释放 ≠ 成功,必须再读 Status(70h)OIP=0 且 (E_FAIL/P_FAIL)=0 → 操作成功;否则按失败恢复流程处理仅依赖 R/B# 会漏掉「完成但失败」状态(如编程写穿、擦除不完全)
图 4 · R/B# 与 Status(70h)双重确认:R/B# 只表示「忙窗口结束」,成功与否以 Status 为准
4.5 R/B# 与 Status 双重确认(强制) 强制

擦写/页读阵列操作期间,R/B# 引脚可能因 上拉过弱、线缆噪声、ESD、控制器采样毛刺、器件内部状态切换瞬间 等原因出现偶发假 Ready;单独一次 Status 读也可能因总线毛刺得到假 Ready 位。

因此:仅观察到一次 Ready,不得判定 Page Read / Program / Erase 完成。

与《SPI NOR》§4.3(WIP 双重确认)、《SPI NAND》§4.4(OIP 双重确认)同级加严;接口不同,语义相同。

实现注意: 本节以下伪代码为唯一合法完成判定模板。禁止再实现“R/B# 变高就返回成功”或“读一次 70h Ready 即成功”的简化逻辑。

强制规则:

  1. 判定 Page Read / Program / Erase 完成前,必须满足:
  2. R/B# 为 Ready,且 连续 ≥2 次 独立读 Status(70h)均为 Ready;或
  3. 无可靠 R/B# 连线时:连续 ≥2 次 Status Ready(两次独立命令事务),并仍强烈建议接 R/B#。
  4. 两次 Status 读之间应有短暂间隔(建议 ≥ 1~10 µs);至少完成两次独立 CLE 70h 事务。
  5. 若第一次 Ready、第二次 Busy:视为未完成,清零确认计数,继续轮询直至双重确认成功或 Timeout。
  6. 双重确认通过后,再检查 Fail / ECC(编擦看 Fail;读看 ECC)。Fail 或不可纠正不得当成功。
  7. DMA/EDMA 半包/全包中断后,禁止用“已传输字节数”代替 Ready 判断——DMA 完成 ≠ 阵列操作完成。
  8. R/B# 上拉过弱或干扰导致毛刺时,以 Status 为准,并记录 rb_glitch 类告警;长期毛刺须改硬件/时序。
  9. Soft Reset、模式切换、故障恢复路径同样适用本规则。

推荐伪代码(标准实现 — 唯一合法模板):

t0 = now()
ready_streak = 0
required = 2          // 连续 Ready 次数,默认 2,可配置 ≥2

do {
    if (rb_pin_is_busy()) {
        ready_streak = 0
    } else {
        st = read_status_70h()       // 独立命令事务:CLE 70h + 读 1B
        if (!status_ready(st)) {     // Ready 位定义须按料号替换
            ready_streak = 0
        } else {
            ready_streak++
            if (ready_streak >= required)
                break
        }
    }
    if (now() - t0 > timeout)
        return PPI_NAND_ERR_TIMEOUT
    yield_or_sleep(poll_interval)    // 建议 10µs~1ms,避免占死 CPU
} while (1)

if (op == PROGRAM && status_fail(st)) return PPI_NAND_ERR_P_FAIL
if (op == ERASE   && status_fail(st)) return PPI_NAND_ERR_E_FAIL
if (op == READ)   return decode_ecc_status(...)  // 见 §6

说明:

  • 部分 Datasheet 仅要求“等 R/B# 再读 Status”;本规范在此基础上加严为 R/B# + 连续两次 Status Ready(或无脚时两次 Status)。
  • Status 位定义(Ready / Fail / WP)因厂而异,能力表必须提供解析掩码;附录 E 仅为模板。
  • Memory-Mapped NFC 读阵列 不得代替 Status 忙判定。
  • 多 LUN / 多 CE# 时,确认的是本次命令目标的状态(必要时用 Enhanced Status 78h 等,以 Datasheet 为准)。

4.6 Cache Read / Cache Program(可选增强) 可选

项 要求
目的 流水化提升顺序吞吐
启用 能力表显式打开;单页路径验证稳定前禁止
退出 异常、BBT 扫描、模式切换、故障恢复前必须回到已知空闲态(必要时 FFh)
错误 Cache 路径同样必须检查 Fail / ECC;禁止“为快而跳过状态”
与锁 Cache 序列必须原子持锁,禁止中途插入其它 Target 命令

4.7 失败与恢复

失败类型 处理
Timeout 记录 op/row/status/R/B#;尝试 Soft Reset;重新 ID;返回 ERR_TIMEOUT
Program Fail 该页/块视为不可靠;标记坏块;返回 ERR_P_FAIL
Erase Fail 标记坏块;返回 ERR_E_FAIL
ECC 不可纠正 返回 ERR_ECC_UNCORRECTABLE;按 §6 整块迁移 + 标记坏块
ECC 可纠正且 bitflip ≥ 迁块阈值(8-bit 默认 ≥6) 按 §6 整块迁移 + 标坏
ECC 可纠正且 bitflip < 阈值 返回成功并上报 corrected bits
时序模式异常 回 SDR + Reset;返回 ERR_TIMING_MODE

5. 坏块管理 BBM(强制) 强制

NAND 出厂允许存在坏块;运行中编程/擦除失败也会新增坏块。无 BBM 的驱动视为不合格。

本节与《SPI NAND》§5 对齐(并行 NAND 本是坏块标记惯例的源头)。

5.1 出厂坏块数量(行业惯例)

项 行业常见约定 软件要求
出厂初始坏块上限 多数 Datasheet 按 不超过总 Block 约 2% 以目标料号为准
零坏块料 部分筛选料可宣称 0 仍须具备运行期 BBM
寿命期新增 P_FAIL/E_FAIL/ECC 仍可能产生 替换池再按 ≥2% 预留
分区影响 坏块可能聚集 小分区按最坏留余量;禁止假设“前 N 块一定好”
总块数 N
出厂坏块预算 ≈ ceil(N × 2%)
运行期替换池  ≥ ceil(N × 2%)
用户可见好块 ≤ N - 出厂已标坏 - 替换池 - BBT/系统保留

扫描每块 Page0(及 Page1)Spare 区首字节,非 0xFF 即判为坏块好块Main 0..NSpare 首字节= 0xFF ✓坏块(出厂)Main 0..NSpare 首字节≠ 0xFF ✗非 0xFF 即标记注:位置依 Datasheet(常见 Column 地址 0x800 / 0x840,Page0 有时含 Page1 冗余)
图 5 · 出厂坏块标记位置:Spare 区首字节约定(常见 0x800),扫描须覆盖 Page0 与冗余 Page1
5.2 出厂坏块标记位置(扫描强制) 强制

项 行业常见约定
判定 规定位置标记字节 ≠ 0xFF
主位置 Block Page 0 Spare/OOB 第 1 字节
辅位置 常同时检查 Page 1 Spare 第 1 字节
末页 少数料号要求;以 Datasheet 为准
×16 器件 标记可能占 1~2 字节;能力表写 bb_marker_len
Main 区标记 极少数老流程;现代料 以 Spare 为准
for block in all_blocks:
    for page in bb_marker_pages:          // 默认 {0, 1}
        raw_read_oob(block, page, off=0, len=bb_marker_len)  // 关 ECC / Raw
        if any_byte != 0xFF:
            mark_factory_bad(block)
            break

典型页布局(2KB+64B 例):

Page 0:
  Main[0 .. 2047] | OOB[0]=BB_MARKER ← 工厂坏块看这里是否为 0xFF
                  | OOB[1 ..] 用户/ECC(ECC on 时部分为 parity,勿当标记)
项 要求
时机 首次擦写之前完成 FBBT;禁止先 Erase 再扫
ECC 扫标记必须 关 On-Die ECC / 关硬件 ECC 或走 Raw
Cache 扫 BBT 前退出 Cache 流水
禁止擦标记 对已识别坏块 禁止 Erase(除受控写运行期标记)
能力表 bb_marker_pages[]、bb_oob_offset、bb_marker_len、是否查 last page

① 触发P_FAIL / E_FAILECC 不可纠正② 搬移数据→备用块顺序写+回读校验③ 标坏Spare 首字节写 0x00④ BBT更新坏块表持久化⑤ 映射逻辑块→新物理块重定向铁律:先搬数据 → 再落标 → 最后改映射;禁止先擦原块、禁止只标不迁掉电可重启:每步完成即持久化,重启后从已完成步继续(幂等)
图 6 · 运行期标坏流程:先迁数据后落标,映射最后改,全步骤掉电可重入
5.3 运行期坏块标记(强制) 强制

项 要求
写入位置 与工厂一致:优先 Page 0 OOB[0]=非 0xFF(常用 0x00);Datasheet 要求则 Page1 同写
流程 先搬迁有效数据 → 写 OOB 标记 → 提交 BBT(掉电安全见 §11)
ECC 写标记按厂商要求 Raw/关 ECC,避免 parity 覆盖标记字节
与用户 OOB 标记字节占用的 offset 不得再给 FTL/FS

触发条件:

  • Program Fail / Erase Fail
  • ECC 不可纠正
  • ECC 可纠正但 corrected bits ≥ 迁块阈值(8-bit 默认 ≥6)

标准动作:

  1. 从空闲好块池分配目标块
  2. 将该坏/濒危块内仍可读的有效页全部搬迁到新好块
  3. 更新 FTL/BBM 映射并提交
  4. 写 OOB 坏块标记 + 更新 BBT 多副本
  5. 向上层返回可区分错误/告警码

5.4 强制禁止 强制

  1. 禁止假设“新片子无坏块”跳过扫描。
  2. 禁止对已知坏块 Erase/Program(除受控写标记)。
  3. 禁止坏块表单副本无备份。
  4. 禁止业务层绕过 BBM 裸写物理地址。
  5. 禁止未扫 FBBT 前全盘 Erase。
  6. 禁止用“Main 是否全 0xFF”代替 OOB 坏块判定。
  7. 禁止在 ECC 开启时用“读到的 OOB 第一字节”直接当工厂标记而不走 Raw。

5.5 保留区规划(推荐) 推荐

区域 说明
BBT 副本区 ≥2 个相隔较远的好块
FTL 超级块/映射 多副本 + 世代号
替换块池 预留 ≥2% 好块;耗尽见 §5.7
OTP/工厂数据 与主数据隔离

魔数版本JEDEC ID表项0表项1…表项NCRC16/32表项 = (坏块物理号, 来源: factory / runtime, 状态)加载策略上电优先加载持久化 BBT(CRC 通过即信任)→ 逐块扫描仅作兜底;双副本分块存放 + CRC 互备;BBT 块从替换池固定划出,禁止写入用户数据
图 7 · BBT 格式:魔数 + 版本 + JEDEC ID + 带来源标记的表项 + CRC;上电优先加载持久化表
5.6 BBT 格式与存放(强制) 强制

项 要求
内容 魔数、版本号、Device ID、容量/几何摘要、坏块位图或列表(区分 factory/runtime)、CRC32
多副本 ≥2 份,分属不同物理 Block;启动选 CRC 正确且世代更新者
与 FBBT 首次扫 OOB 生成;运行期坏块合并,不得丢掉工厂坏块
启动 优先加载持久化 BBT;仅工厂/维修/BBT 全损时全盘扫描
更新 标坏后先写新 BBT 再提交
禁止 无版本无 CRC;单副本;与可 GC 用户数据混放无钉扎

5.7 替换池耗尽降级(强制) 强制

状态 行为
池水位低(如剩余 < 0.5% 或 < N 块) 告警,仍可写
池空 返回 PPI_NAND_ERR_NO_SPARE
耗尽后 只读/降级;拒绝用户擦写
上报 spare_exhausted 对云端/UI 可见
恢复 维护模式换片或重建
扫码打开本页
微信扫码 · 展会可扫

再分享给同事

同事可直接打开这份资料《并行NAND_PPI_NAND_软件设计规范》,在线阅读;完整章节请下载芯参谋。