只读分享解决方案文档调试&解决方案📅 2026-09-21🔖 Rev 1.0⏳ 29天有效(至 2026-10-31)
🔧解决方案&应用市场分析 -> 调试&解决方案 -> 系统设计指南 -> SPI_NOR_BP块保护功能_设计方案

SPI_NOR_BP块保护功能_设计方案

生成时间 2026-09-28 13:34:41 有效期至 2026-10-31 23:59:59(29天有效(至 2026-10-31))
同系列 · 调试&解决方案

SPI NOR 块保护(BP)功能设计方案

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

从 BP/TB/SEC/CMP 四个位、保护分区规划、WP# 引脚设计,到驱动实现与量产加锁时机的完整落地方案

先读这一条:本文所有位定义以主流通用器件为例
  • 文中寄存器位名、保护档位、命令码取自主流 SPI NOR 通用架构(如 W25Q / MX25 / GD25 一类),用于讲清机制;你在做的料号必须以 XTX 正式 datasheet 为准,尤其是 BP 位数、TB 极性、是否存在 CMP 与 WPS 位。
  • SPI NOR 与 SPI NAND 的 BP 机制不同源(默认值、TB 极性、WP# 语义都不一样),不要互相套用。NAND 侧请看同系列《SPI NAND 块保护(BP)功能设计方案》。
  • 涉及 OTP / SRL 非易失写 1 / 永久锁定 的操作不可逆,必须在小批量验证通过、量产 SOP 冻结之后再执行。
3 层
BP 的防护层次
区域锁 → 寄存器锁 → 硬件引脚锁
4 位
决定保护区的寄存器位
BP[2:0] / TB / SEC / CMP
1/64
CMP=1 时的最小保护粒度
CMP=0 时最小只能保护 1/2
0 报错
保护生效时的错误反馈
命令被静默丢弃,必须回读验证

一句话结论:SPI NOR 的 BP 不是「把三个位写进去」这么简单,而是分区规划 → 档位换算 → 引脚设计 → 驱动时序 → 产线加锁时机五件事的串联。其中最容易翻车的是档位换算:CMP=0 时能保护的最小范围是 1/2,想只锁 64 KB 的 Bootloader,必须先把 CMP 置 1 反转语义——而这个反转本身就是「清 BP 反而锁死整片」事故的来源。

这份文档解决什么

块保护(Block Protect,简称 BP)是 SPI NOR 里成本最低、也最容易被做错的一道防护。它不加密、不鉴权,只是在芯片内部给地址空间画一条线,让跨越这条线的擦除和编程命令被静默忽略。正因为它「静默」,做错的时候往往不报错——你以为写进去了,其实芯片早就把命令丢了。

本分册只讲 SPI NOR:从 SR-1/SR-2/SR-3 三个状态寄存器里与保护相关的位讲起,把 BP / TB / SEC / CMP 四个位怎么联合决定保护区说透,再给出分区怎么规划、WP# 怎么接、驱动怎么写、产线在哪一步加锁、加锁之后 OTA 怎么办,最后是速查表与核查清单。

定位「为什么写不进去」的故障排查请看同系列《写保护误触发_SR_BP位_量产排查》;SPI NAND 与并行 NOR(PPI NOR)的保护机制完全是另一套,各有独立分册。

需求 1
固件 / Bootloader 防误擦
OTA 或产线误操作把启动区擦掉,设备变砖。用 BP + CMP 把启动区锁成只读,擦写命令对这段地址直接无效。
高发:小资源 MCU 无 MPU 的场景
需求 2
校准参数 / SN / MAC 防改写
射频校准值、SN、MAC 一旦被覆写,整机功能异常且难以追溯。把参数区搬到与 Boot 同侧,一起用 BP 锁住。
高发:共用一片 Flash 的紧凑方案
需求 3
量产防误操作与一致性
烧录站参数卡填错、工程模式残留未清除,导致整批芯片状态不一致。把目标 SR 值固化进参数卡并强制写入后回读校验。
高发:多料号共线生产
需求 4
密钥固化与安全启动配合
BP 挡不住读出,但配合 OTP 区(部分料号提供)与 UID 可以做出「密钥不可改 + 固件不可改」的组合,构成轻量安全启动的基础。
注意:BP 本身不提供保密性

1. BP 保护的本质:它锁住的是命令,不是数据

在动手配寄存器之前,先要接受一个事实:BP 生效时芯片不报错。理解这一点,后面所有的验证方法都要围绕「回读校验」而不是「看有没有报错」来设计。

SPI NOR 的三层防护链:任何一层没做,保护就能被绕过主机擦写请求Page Program /Sector / Block Erase第 1 层 · 区域锁BP / TB / SEC / CMP决定哪些区间拒写第 2 层 · 寄存器锁SRP0 / SRL决定 SR 能不能被改第 3 层 · 硬件锁WP# 引脚电平(由 WPS 选择语义)三层是串联关系:只写 BP 位而 WP# 上拉,软件随时能解锁;只拉 WP# 而 BP=000,等于什么都没锁。
图 1 · SPI NOR 的三层防护链:任何一层没做,保护就能被绕过

1.1 BP 锁的是命令,不是数据

BP 生效时,芯片不会拒绝你的命令、也不会报错——它照常接收地址和数据,然后在内部判断「这段地址在保护区内」,于是把这次擦除或编程直接丢弃。所以 BP 配置错误最典型的现场表现不是报错,而是「烧录工具显示成功,回读却是旧数据」。

BP 是拒绝服务,不是加密

BP 只在芯片内部拦住擦写命令,它不加密数据、不做鉴权、也不阻止读出。任何人把芯片拆下来接到编程器上,只要能改状态寄存器,保护就能被解除。需要保密性请配合 OTP 区与 UID 加密方案,需要防拆请考虑物理防护。

1.2 三层防护,缺一层就等于没锁

层次由谁决定挡住什么挡不住什么
第 1 层 · 区域锁SR-1 的 BP[2:0] / TB / SEC,SR-2 的 CMP对保护区内地址的 Page Program、Sector/Block Erase、Chip Erase 命令对状态寄存器本身的写入
第 2 层 · 寄存器锁SR-1 的 SRP0 + SR-2 的 SRL在软件层面改写状态寄存器(即「先解锁再擦」这条路)硬件引脚被拉到允许电平的情况
第 3 层 · 硬件锁WP# 引脚电平 + SR-3 的 WPS 位在板状态下的一切软件解锁尝试把芯片拆下来单独烧录
最常见的设计缺陷:WP# 引脚悬空或直接上拉到可写电平

很多原理图把 WP# 留成 NC 或直接拉到 VCC,认为「反正不接就是没保护」。实际上 WP# 悬空会让引脚电平在噪声下抖动,保护状态随机翻转;而固定拉到可写电平,则意味着任何软件都能解锁 BP,第 1 层锁形同虚设。详见第 6 章的三种接法。

1.3 上电默认态:NOR 是无保护

SPI NOR 出厂 / 上电后 BP[2:0] = 000、TB = 0、SEC = 0、CMP = 0、SRP0 = 0,也就是整片可擦写、SR 随时可改。这是一个「默认开放」的设计:好处是产线拿来就能烧,坏处是保护必须靠后续工位主动去写——漏了这一步,整批产品裸奔,而外观和功能测试全都正常,发现不了。

与 SPI NAND 的对比(换料号时必看)

SPI NAND 上电默认 整片保护,SPI NOR 上电默认 无保护。两者方向完全相反。团队用 NOR 调通后换 NAND,第一反应通常是「料号不良 / 虚焊」,实际只是没发解锁命令。反过来从 NAND 换到 NOR,则要警惕「以为有保护、其实一片没锁」。

2. 寄存器地图:三个状态寄存器里与保护相关的位

BP 的复杂度不在命令,而在「哪几个位在联合起作用」。把这张位图看明白,后面所有计算才不会算错。

SPI NOR 三个状态寄存器中与保护相关的位SR-1(0x05 读)bit7SRP0bit6SECbit5TBbit4BP2bit3BP1bit2BP0bit1WELbit0BUSY保护区与方向:BP 定范围、TB 定顶/底、SEC 定粒度SR-2(0x35 读)bit7SUSbit6CMPbit5LB3bit4LB2bit3LB1bit2保留bit1QEbit0SRLCMP 反转保护语义;SRL 决定寄存器锁级别(含不可逆档)SR-3(0x15 读)bit7HOLD/RSTbit6DRV1bit5DRV0bit4保留bit3保留bit2WPSbit1ADPbit0ADSWPS 决定 WP# 引脚是「电平说了算」还是「寄存器说了算」位名沿用主流器件命名(如 W25Q 系列);具体料号请以 datasheet 寄存器图为准。
图 2 · SPI NOR 三个状态寄存器中与保护相关的位

2.1 三个状态寄存器怎么读、怎么写

寄存器读命令写方式与保护相关的内容
SR-105h01h 的第一字节(或单字节 WRSR)BUSY / WEL / BP[2:0] / TB / SEC / SRP0
SR-235h01h 的第二字节(16-bit WRSR,31h / 01h 视料号)SRL / QE / LB[3:1] / CMP / SUS
SR-315h01h 的第三字节(11h / 01h 视料号)ADS / ADP / WPS / DRV[1:0] / HOLD·RST 复用选择
16 位 WRSR 会同时改 SR-1 和 SR-2

只想改 BP 位却只发了一个字节,或者第二个字节填了 0x00——很可能顺手把 QE 位清掉,芯片从 Quad 退回单线,表现为读取速度骤降、甚至 XIP 时序不满足而跑飞。正确做法是:先读回 SR-2 的当前值,只改目标位,其余位原样回填。

2.2 每个位的一句话解释

位所在寄存器类型一句话
BP[2:0]SR-1 bit4:2非易失保护范围档位,000 = 无保护,111 = 全片保护
TBSR-1 bit5非易失保护方向:0 = 从低地址端起算,1 = 从高地址端起算
SECSR-1 bit6非易失粒度:0 = 按 64 KB 块计,1 = 按 4 KB 扇区计
CMPSR-2 bit6非易失语义反转:1 = 保护区与开放区整体互换
SRP0SR-1 bit7非易失寄存器锁使能:置 1 后 SR 的可写性受 WP# 控制
SRLSR-2 bit0非易失(易失写可选)寄存器锁级别:置 1 后 SR 锁定;非易失写则不可逆
WPSSR-3 bit2非易失WP# 语义选择:0 = 引脚模式,1 = 寄存器模式
LB[3:1]SR-2 bit5:3一次性(OTP)安全寄存器(Security Register)锁定位,写 1 不可逆
WELSR-1 bit1易失写使能锁存,每次写 SR / 擦 / 写前都要重新发 06h
BUSYSR-1 bit0只读器件忙标志,写 SR 与擦写后必须轮询到 0
WEL 与 BUSY 是易失 / 只读位,别把它们写进目标值

构造要写入的 SR 字节时,BUSY 与 WEL 位不参与——它们是只读或自动清零的。把目标值直接写死成 0x0C 这类常量是对的,但如果你先读回 SR 再改位,记得把 bit1/bit0 屏蔽掉再回填,否则可能把 WEL 位算进去,凑出一个错误的字节。

2.3 4 字节地址器件(> 128 Mb)的额外注意事项

容量大于 128 Mb 的器件需要进入 4 字节地址模式(或配合地址长度切换)才能访问高地址空间,此时要额外确认三件事:

  • 保护档位表是否按新容量重算:同一 BP 编码在 16 MB 与 32 MB 器件上对应的绝对容量不同,档位比例不变但边界地址变了。
  • 写 SR 命令的字节数是否变化:部分料号在 4 字节模式下写 SR 的指令码不同(如 01h / 3Eh 的区分),写错会被静默忽略。
  • ADS / ADP 位(SR-3):决定上电后的默认地址长度与 4 字节指令是否启用,若配置不当,保护区的实际地址会偏移,出现「看着锁对了其实锁错位」。

3. 保护区怎么算:BP / TB / SEC / CMP 四把钥匙

NOR 的 BP 是一个「范围 + 方向 + 粒度 + 语义」的四维组合。只看 BP 三个位,一定会算错保护区。

3.1 把 BP 想成一把从某一端量起的尺子

TB 决定从哪一头量,SEC 决定刻度是 64 KB 还是 4 KB,BP[2:0] 决定量多长,CMP 决定「量到的部分被保护」还是「量到的部分反而开放」。四者必须一起算,只看 BP 三个位一定会算错。

位作用取值含义
BP[2:0]保护范围000 = 无保护;111 = 全片保护;中间档按比例递增(见 3.2 表)
TB方向0 = 从低地址端起算;1 = 从高地址端起算
SEC粒度0 = 按 64 KB 块计;1 = 按 4 KB 扇区计(边界更精细)
CMP语义反转0 = 正常;1 = 保护区与开放区整体互换
SPI NOR 保护区由 TB / SEC / CMP / BP 四者共同决定TB=0 · BP=110CMP=0(默认)保护区(低 1/2)可擦写TB=1 · BP=110CMP=0(默认)可擦写保护区(高 1/2)SEC=1 · BP=1004 KB 扇区粒度,边界更细保护区可擦写CMP=1 · BP=011语义反转:只保护顶部一档可擦写保护区低地址地址空间(示意,比例非实际档位)高地址
图 3 · SPI NOR 保护区由 TB / SEC / CMP / BP 四者共同决定

3.2 保护档位速查(CMP=0、SEC=0,通用规律)

BP[2:0]TB=0(保护低地址)TB=1(保护高地址)CMP=1 时的等效效果
000无保护无保护全片保护
001低 63/64高 63/64仅保护对侧 1/64
010低 31/32高 31/32仅保护对侧 1/32
011低 15/16高 15/16仅保护对侧 1/16
100低 7/8高 7/8仅保护对侧 1/8
101低 3/4高 3/4仅保护对侧 1/4
110低 1/2高 1/2仅保护对侧 1/2
111全片保护全片保护无保护
为什么 CMP 这么重要:CMP=0 时最小只能保护 1/2

看上表就能发现:CMP=0 时你能保护的最小范围是 1/2——想只锁 Bootloader 那 64 KB 根本做不到,最小也会锁掉半个芯片。而 CMP=1 把语义反转,BP=001 就变成「只保护对侧 1/64」,这才是小范围保护的正确做法。代价是:配置顺序必须先清 CMP,再改 BP,否则你「清 BP」的动作反而会把整片锁死。

3.3 SEC 位:4 KB 粒度能救回多少精度

SEC=1 时保护边界按 4 KB 扇区而不是 64 KB 块对齐。在 CMP=1 + 小档位场景下,SEC=1 可以让你把保护区边界卡得更准;但在 CMP=0 + 大档位场景下,SEC 的影响可以忽略。判断标准很简单:

场景SEC 该取多少理由
要保护的范围 ≥ 数 MB(比例档位)SEC=0 即可边界本来就在 64 KB 量级,4 KB 精度无意义
CMP=1 保护几十~几百 KBSEC=1档位边界与真实分区边界的偏差可缩小到 4 KB 内
分区表按 4 KB 扇区对齐设计SEC=1让分区边界与保护边界用同一套刻度
不确定SEC=1代价几乎为零,精度只增不减(除非档位表对 SEC=1 有专门定义)
SEC=1 时档位表可能不同

部分料号在 SEC=1 时给出的是另一张档位表(因为最小单位变了)。不要假设「SEC 只影响边界精度、不影响档位比例」,拿到料号后要对着 datasheet 里的 Sector/Block Protection Table 核一遍。

4. 寄存器锁:SRP0 / SRL / WPS 与不可逆的 LB 位

只配 BP 不配寄存器锁,等于给门装了锁芯却把钥匙插在门上。这一章决定这套保护到底能挡住谁。

SRL 与 SRP0 的四种组合:①②是主力方案,④是单向门① 出厂默认SRL=0, SRP0=0WREN 后 SR 随时可改;WP# 无控制作用② 引脚参与的硬件锁SRL=0, SRP0=1, WP#=0SR 被锁定,需把 WP# 拉高才能改③ 易失寄存器锁SRL=1(易失写)本次上电期间 SR 不可改,掉电自动恢复④ 永久寄存器锁SRL=1(非易失写)SR 永久锁定,不可逆,只能换芯片组合 ③ 与 ④ 的寄存器位值相同,区别只在于写入命令是易失还是非易失。
图 4 · SRL 与 SRP0 的四种组合:①②是主力方案,④是单向门

4.1 第 1 层锁管「哪些区域不能写」,第 2 层锁管「BP 位能不能被改」

如果只做了第 1 层,那么任何一段跑在设备上的代码——包括被攻破的应用固件——都可以先发 06h 再把 BP 清成 000,然后随意擦写启动区。第 2 层锁(SRP0 / SRL)就是用来堵这条路的。

SRLSRP0WP# 引脚状态寄存器可写性说明
00X(任意)WREN 后可写出厂默认:WP# 无控制作用,软件全权
01低电平锁定,不可写硬件保护:需要 WP# 拉高才能改 SR
01高电平WREN 后可写硬件未保护:仍需 WREN 才能写
1XX锁定易失写入 = 掉电解锁;非易失写入 = 永久锁定(OTP),不可逆
SRL 是单向门:同一个位值,两种命运

SRL 置 1 之后:如果是易失写入,掉电一次即可恢复,可以用来做「本轮上电期间禁止改保护」的临时锁;如果是非易失写入,则是一次性编程(OTP),永久不可逆。两者寄存器值完全一样,从回读结果上区分不出来——区别只在你发的是哪一条写命令。下达非易失写命令前必须确认:保护配置已经过完整验证、且未来 OTA 不需要再改保护区。

4.2 WPS:WP# 引脚到底听谁的

SR-3 的 WPS(Write Protect Select)位决定 WP# 引脚的语义来源,这是 SPI NOR 比 NAND 多出来的一个开关:

WPS模式WP# 引脚的作用
0引脚模式WP# 电平直接决定 SR 是否可写:拉低即锁 SR,拉高才允许(仍须先发 WREN)
1寄存器模式由 SR 内部的 SRP0 / SRL 决定锁定状态,WP# 退居辅助或不生效
在板烧录失败时,先看 WP# 再看 BP

软件层面把 BP 清得再干净,只要 WP# 被拉低且 WPS=0,状态寄存器照样写不进去,现象和「芯片锁死」一模一样。在板烧录失败时,WP# 电平与 WPS 位是与 BP 同等优先级的排查项,而且量一个引脚电平比读寄存器还快。

4.3 安全寄存器(Security Register)与 LB 位

部分料号除了主阵列还提供若干安全寄存器(典型 256 B × 3),由 SR-2 的 LB[3:1] 三个位分别锁定。这三个位是一次性编程(OTP)的:写 1 之后对应安全寄存器永久只读,且该位本身也再也改不回来。

典型用途是存放设备唯一标识、出厂校准值、公钥指纹。它与 BP 的区别在于:BP 管的是主阵列的地址区间,LB 管的是独立的安全寄存器;LB 锁定的粒度是「整个安全寄存器」,不能按字节。

把 LB 与 BP 组合起来的典型布局

BP + CMP 锁住 Bootloader(可擦写区之外的启动代码),安全寄存器 + LB 锁住设备身份与密钥指纹,主阵列其余部分留给 APP 与文件系统。这样即使 APP 被完全攻破,攻击者既改不了启动链,也改不了设备身份。