STM32 RDP保护通过HAL_FLASHEx_OBProgram配置选项字节实现:Level 1(0x55)可逆,擦除后恢复;Level 2(0xCC)不可逆,永久禁用调试与Flash访问,需先解锁Flash和OB,写入后调用HAL_FLASH_OB_Launch生效。

直接用 HAL_FLASHEx_OBProgram 设置 RDP 级别
HAL 库里没有叫 enableRDP() 这种封装函数,所有选项字节操作必须走 HAL_FLASHEx_OBProgram()。它本质是把配置写进 Flash 的 Option Bytes 区(物理地址如 0x1FFFC000),不是运行时开关。设置前必须调用 HAL_FLASH_OB_Unlock(),否则写入失败且无报错——这是量产烧录时最常见的静默失败原因。
关键点在于:RDP 是一次性写入的字节值,不是布尔开关。Level 1 对应 OB_RDP_LEVEL_1(实际写入值通常为 0x55),Level 2 对应 OB_RDP_LEVEL_2(写入 0xCC)。HAL 库会自动校验并处理字节掩码,但你不能手动往 FLASH->OPTCR 寄存器写值——那属于 LL 库或寄存器直操范畴,极易出错。
- 必须先调用
HAL_FLASH_Unlock(),否则HAL_FLASH_OB_Unlock()会失败 - 写完后务必调用
HAL_FLASH_OB_Launch(),否则新 RDP 值不会生效(芯片仍按旧值判断) -
HAL_FLASH_OB_Lock()和HAL_FLASH_Lock()要成对调用,防止后续误操作擦除 Option Bytes
RDP Level 1 和 Level 2 的行为差异远超“多锁一层”
Level 1 是可逆保护:调试器连不上、读不到 Flash,但全片擦除(Mass Erase)后 RDP 自动降回 Level 0,Flash 数据清空,芯片恢复可编程状态。这是产线烧录和现场升级的底线保障。
Level 2 是物理熔断:一旦写入 0xCC,SWD/JTAG 接口永久失效,Mass Erase 命令本身也被芯片硬件拒绝执行。这不是软件锁,是芯片内部保险丝级操作。实测过 STM32F407,ST-LINK Utility 点“Erase All”直接报错 Failed to erase memory,且无法通过任何方式恢复调试能力。
立即学习“C++免费学习笔记(深入)”;
- Level 2 不是“更安全的 Level 1”,而是“放弃售后通道”的终极选择
- 部分型号(如 STM32L4+)在 Level 2 下仍允许通过系统存储器 Bootloader 升级,但无法读取或验证 Flash 内容
- HAL 库中
OB_RDP_LEVEL_2宏定义存在,但部分老版本固件库未开放该功能,需确认stm32f4xx_hal_flash_ex.h中是否声明
别在 main() 开头就调用 RDP 配置函数
很多工程师把 RDP 设置代码塞进 main() 第一行,结果一上电就锁死芯片——因为此时调试器还在连接握手阶段,程序刚跑起来就被 RDP 切断了 SWD 通路,J-Link 报 No target connected,连 debug log 都打不出来。
正确做法是:只在量产烧录最后一道工序执行 RDP 设置;或者加硬开关(如某个 GPIO 拉低才执行),确保开发阶段完全绕过该逻辑。我们曾因没加开关,导致 300 片板子全部变砖,只能用 ST-LINK Utility 的“Option Bytes”页手动恢复(前提是还没进 Level 2)。
- 绝对不要在未验证固件稳定性的前提下启用 RDP
- 启用前确保已关闭所有看门狗(或启用硬件看门狗并喂狗),否则
HAL_FLASH_OB_Launch()后复位失败,芯片卡死 - 若用 CubeMX 生成代码,检查
SystemClock_Config()是否在 RDP 设置前完成,否则 Flash 控制器时钟异常会导致写入失败
验证 RDP 是否真正生效,别信 IDE 的“连接成功”提示
ST-LINK Utility 或 STM32CubeProgrammer 显示 “Connected” 并不表示 RDP 无效——它们可能只是连上了 SWD 接口,但读 Flash 时才会触发保护。真正验证方式只有两种:
- 在 ST-LINK Utility 中点击
Target → Read Memory,起始地址填0x08000000,长度设 0x100;若返回全0x00或全0xFF(非真实代码内容),说明 RDP Level 1 已生效 - 用 OpenOCD 命令行执行
dump_image out.bin 0x08000000 0x100,若输出文件全是 0,即为保护成功 - 注意:某些调试器(如 J-Link)在 Level 1 下会返回随机值(如全
0xAA),而非固定 0,这是芯片厂商故意设计的防探测机制
RDP 的核心作用不是加密数据,而是阻断标准读取路径。只要调试器拿不到真实 Flash 内容,逆向者就必须转向成本极高的物理攻击(如去封装+FIB),这对绝大多数产品已是足够门槛。


















