并行 NOR(PPI NOR)扇区保护设计方案
编制日期 2026-09-21 | 版本号 Rev 1.0
从 PPB 非易失逐块保护、DYB 易失逐块保护、PPB Lock 冻结,到 WP#/ACC 引脚、CFI 命令序列、驱动实现与量产加锁时机的完整落地方案
- 文中 PPB / DYB / PPB Lock / Lock Register / WP# / ACC 等机制取自通用 CFI 并行 NOR 架构(如 S29GL / S29VS 一类),用于讲清机制;你手上的料号必须以正式 datasheet 为准,尤其是解锁序列的地址与命令字(8 位 / 16 位总线下的偏移不同)。
- 并行 NOR 与 SPI NOR / SPI NAND 的保护完全不是一套体系:没有「滑动区间 + CMP 反转」,而是逐 block 的 PPB / DYB 独立位。不要互相套用。
- 涉及 PPB Lock 冻结、Lock Register OTP、密码模式 的操作不可逆,必须在小批量验证通过、量产 SOP 冻结之后再执行。
一句话结论:并行 NOR 的扇区保护与 SPI 那套「滑动区间 + 位运算」完全不同:它是每个擦除 block 一个独立的 PPB 位(非易失、掉电保留)加一个 DYB 位(易失、复位清零),外加 WP#/ACC 硬件保护最外两块。因为按 block 独立,规划反而比 SPI 简单——锁哪几块就写哪几位的 PPB,不需要「向上取整到档位」。代价是命令是CFI 解锁序列,地址 / 命令字必须严格对照 datasheet,且 PPB 一旦编程就是非易失的。
这份文档解决什么
并行 NOR(Parallel NOR,常称 PPI NOR)走的是地址 / 数据并行总线 + CFI 命令集。它的扇区保护不靠几个位拼出一个区间,而是给每一个擦除 block 配一个独立的保护位:PPB(Persistent Protection Bit,非易失)和 DYB(Dynamic Protection Bit,易失)。
本分册只讲并行 NOR:先讲清楚它的保护架构(PPB / DYB / PPB Lock / Lock Register / WP# / ACC),再拆解命令序列怎么发、分区怎么规划、WP# 和 ACC 引脚怎么接、驱动怎么写、产线在哪一步加锁、加锁之后 OTA 怎么办,最后是速查表与设计核查清单。
SPI NOR / SPI NAND 的保护机制完全不同源,各有独立分册;定位「为什么写不进去」的故障排查请看同系列《写保护误触发_SR_BP位_量产排查》。
1. 扇区保护的本质:逐 block,不是滑动区间
并行 NOR 不靠「几个位拼出一段连续区间」,而是给每个擦除 block 一个独立的保护位。理解这一点,后面所有的规划与命令都要围绕「block 级」而不是「区间级」来设计。
1.1 扇区保护锁的是命令,不是数据
保护生效时,器件不会拒绝命令、也不会报错——它在内部判定「这个 block 受保护」,于是把这次编程或擦除直接丢弃。所以配置错误最典型的现场表现不是报错,而是「烧录工具显示成功,回读却是旧数据」。
它只在芯片内部拦住擦写命令,不加密、不做鉴权、也不阻止读出。任何人把芯片拆下接到编程器上,只要能用正确命令解开 PPB,保护就失效。需要保密性请配合 Lock Register OTP / 密码模式,需要防拆请考虑物理防护。
1.2 三层防护,缺一层就可能被绕过
| 层次 | 由谁决定 | 挡住什么 | 挡不住什么 |
|---|---|---|---|
| 第 1 层 · 块保护 | PPB / DYB 逐 block 位 | 对受保护 block 的 Program、Block Erase 命令 | 对 PPB 阵列本身的改写 |
| 第 2 层 · 配置冻结 | PPB Lock / Lock Register | 在软件层面改写 PPB / DYB(即「先解锁再擦」这条路) | 硬件引脚被拉到允许电平的情况 |
| 第 3 层 · 硬件锁 | WP# 引脚电平 | 在板状态下对最外两块的一切软件解锁尝试 | 把芯片拆下来单独烧录 |
只把某个 block 的 PPB 置 1,但 PPB Lock 没设、WP# 又固定高电平,意味着任何跑在设备上的代码都能发命令把 PPB 清 0,然后随意擦写启动区。要真正防住,至少要叠加 PPB Lock(冻结配置)或 WP# 硬件保护。
1.3 上电默认态:并行 NOR 是开放的
全新 / 擦除后的并行 NOR,所有 PPB、DYB 默认为 0(不保护),WP# 通常为高电平(不保护)。这与 SPI NOR 一致、与 SPI NAND(默认整片保护)相反。好处是产线拿来就能烧,坏处是保护必须靠后续工位主动去写 PPB——漏了这一步,整批产品裸奔,而外观和功能测试全都正常。
SPI NOR 与并行 NOR:默认开放;SPI NAND:默认整片保护。团队在三者之间切换料号时,第一件事就是确认默认态——否则会出现「NAND 烧不进去误判不良」或「NOR 以为有保护其实没锁」。
2. 保护架构地图:PPB / DYB / Lock / 引脚
并行 NOR 没有一个「状态寄存器里几个 BP 位」的概念,而是 PPB(非易失逐块)、DYB(易失逐块)、PPB Lock(冻结)、WP#/ACC(硬件)四者协同。
2.1 四种机制怎么分工
| 机制 | 存储属性 | 保护范围 | 复位 / 掉电行为 | 改写受控于 |
|---|---|---|---|---|
| PPB | 非易失 | 单个 block | 保留 | PPB Lock |
| DYB | 易失 | 单个 block | 清零(开放) | 命令序列(无锁时) |
| PPB Lock | 易失 / OTP(视料号) | 整个 PPB 阵列 | 清零 / 锁定(视料号) | Lock Register / 命令 |
| WP# / ACC | 纯硬件 | 最外两块 | 随引脚电平 | 不可软件改 |
PPB 是非易失的:你写一次,掉电后还在,适合「出厂固化」的保护。DYB 是易失的:复位即清零,适合「本次运行期间临时保护」。两者都置 1 才都保护;只靠 DYB 的话,掉一次电保护就丢了。量产要的是 PPB(持久),调试临时防呆可以用 DYB。
2.2 PPB Lock 与 Lock Register
PPB Lock Bit 是保护「保护配置本身」的开关:置 1 之后,整个 PPB 阵列不可再被改写,于是之前写好的逐 block 保护被冻结,软件再也无法解开。在多数 CFI 器件上它是易失的(复位即解锁),少数料号可配合 Lock Register(含 OTP 位)把它永久固化——这就成了不可逆操作。
Lock Register 是部分并行 NOR 提供的寄存器(常含若干 OTP 位),可把「是否启用密码模式」「PPB Lock 是否永久」等策略固化。它与 SPI NOR 的 SRL / SPI NAND 的 SR1-L 地位相当:写一次就不可逆。
2.3 WP# 与 ACC 引脚
| 引脚 | 作用 | 备注 |
|---|---|---|
| WP# | 低电平保护最外两块(top 或 bottom,由配置决定) | 纯硬件,软件无法绕过;与 PPB 互补覆盖「最容易被忽略的启动块」 |
| ACC | 加速编程(提高 VCC 至加速档) | 在部分模式下可覆盖 WP#,需谨慎处理电平 |
和 SPI 的「滑动区间」不同,硬件 WP# 的范围固定就是地址两端的启动块(具体是 top 还是 bottom 由器件配置位决定)。所以它适合兜住「启动代码所在的那一两块」,而中间的个性化分区要靠 PPB 逐 block 去锁。
3. 保护机制详解:优先级与命令序列
判定顺序是 DYB → PPB → WP#;命令是 CFI 解锁序列。PPB 编程保护单个 block,All PPB Erase 一键全清——两者都要慎用。
3.1 判定顺序:DYB 最高,PPB 次之,WP# 最后
每当收到一次 Program / Block Erase,器件按 DYB → PPB → WP# 的顺序短路判定:任意一层判定为「保护」,本次命令即被丢弃。这也意味着:想临时、即时地保护一个 block,置 DYB=1 最快(易失、复位恢复);想持久保护,写 PPB=1。
| 场景 | 应置位 | 效果 | 掉电后 |
|---|---|---|---|
| 出厂固化保护某 block | PPB=1 | 持久保护 | 保留 |
| 本次运行临时保护 | DYB=1 | 即时保护 | 丢失(清零) |
| 解锁某 block(仅当未被 Lock) | 清 PPB=0(All PPB Erase 或单 block 清) | 开放该 block | 保留(PPB 已清) |
| 硬件兜底最外两块 | WP# 拉低 | 最外两块强制保护 | 随电平 |
3.2 命令序列:通用 CFI 解锁模式
并行 NOR 的所有「写配置」操作都遵循解锁序列(unlock sequence):先向约定地址写 0xAA、再写 0x55,然后才是真正的命令字。以 8 位字模式为例,地址是 0x555 / 0x2AA;在 16 位字模式下,所有命令地址左移 1 位(0xAAA / 0x554)。PPB 编程把解锁后的「编程命令」指向目标 block 的地址并写入保护数据。
不同厂商、不同代次的并行 NOR,解锁地址、命令字(是 0xA0 还是别的)、PPB 阵列的访问方式可能不同。# 上面给的是通用模式,落到项目上必须拿 datasheet 的「Command Definitions」表逐条核对,特别确认 8 位 / 16 位总线下的地址偏移。
3.3 PPB 编程 vs All PPB Erase
| 操作 | 作用 | 易错点 |
|---|---|---|
| PPB Program(单 block) | 把某个 block 的 PPB 置 1(保护) | 目标地址必须指向该 block 的任一地址,写错 block 等于没锁 |
| All PPB Erase(整片清) | 把所有 PPB 一次性清 0(全开放) | 这是「解锁全部」的快捷方式,但不可逆地清掉所有已配置保护,慎用 |
| DYB Set / Clear | 置 / 清单个 block 的 DYB | 易失:复位即丢,不能当持久保护用 |
很多烧录工具在「全片擦除」前会自动发 All PPB Erase,结果你以为只清了数据、其实把保护配置也清了。如果在产线「先清 PPB 再重配」,必须确保重配步骤一定执行——否则会出现「烧完发现整片没保护」。
4. 保护分区规划:逐 block 独立,反而更简单
并行 NOR 没有「滑动区间 + 档位取整」的烦恼,锁哪几块就写哪几位的 PPB。代价是粒度绑定到擦除 block 大小。
4.1 因为逐 block,规划比 SPI 简单
SPI NOR / NAND 的保护是「从一端量起的连续区间」,必须向上取整到档位、还可能溢出吃掉相邻分区。并行 NOR 的 PPB 是每个 block 一个独立位,所以规划非常简单:锁哪几块就写哪几位的 PPB,其余 block 保持开放,不存在「取整」「溢出」问题——代价是粒度被绑定到擦除 block 大小。
4.2 六步规划法
- 列出分区表:偏移、大小(以 block 为单位)、是否可写、更新频率。
- 标出「必须只读」的 block:Boot、校准参数、SN/MAC、密钥。
- 确认 block 边界:保护粒度 = 擦除 block 大小(典型 64 / 128 / 256 KB),分区必须按 block 对齐。
- 把目标 block 列表翻译成 PPB 写操作:每个要保护的 block 发一次 PPB Program。
- 决定是否冻结:若需防软件解锁,置 PPB Lock(或 Lock Register OTP)。
- 回读每个 PPB 确认:逐 block 读回保护状态,确保一个没漏。
4.3 与 OTA 的冲突
OTA 升级时要擦写 APP 所在的 block,而 PPB 是非易失的——上电就在,不会因为跑 OTA 消失。设计时必须确认:OTA 目标 block 全部落在未受保护(PPB=0)的范围内。并行 NOR 的优势是:如果新固件占用更多 block,只需把新增的 block 也保持 PPB=0,不必像 SPI 那样「重算整段区间」。
虽然不用重算区间,但新增 / 调整的 block 是否该保护、是否已写入 PPB 仍要复核。一个常见失误:OTA 后固件体积变大,尾部 block 刚好落在某个被 PPB 锁住的旧参数区,导致升级显示成功、重启却是半成品。