场景
芯片用 ST-Link 下载第一次报错:
Error: Flash Download failed - Target DLL has been cancelled
Internal command error
或者 CubeProgrammer 连接时提示 RDP Level 1。
说明芯片的 Flash 被读保护 了。这种保护叫 RDP(Read Protection),存在选项字节(Option Bytes)里。
什么是选项字节
选项字节是 STM32 芯片的一小段独立配置区域(不在主 Flash 里),用来设置:
-
RDP:读保护等级
-
User option bytes(用户选项字节):独立看门狗/窗口看门狗硬件使能
-
BOR:掉电复位阈值
-
nRST_STDBY:Standby 模式复位功能
三种 RDP 等级
| 等级 | 值 | 说明 |
|---|---|---|
| Level 0 | 0xAA | 无保护(出厂默认) |
| Level 1 | 0xBB | Flash 不允许调试器读取(可通过全片擦除降回 Level 0) |
| Level 2 | 0xCC | 永久保护,不可降级,芯片变一次性 |
Level 1 是常见的"锁死"状态。可能来自:
-
二手芯片
-
项目里主动启用过
-
CubeProgrammer 误操作
检查 RDP 等级
用 STM32CubeProgrammer:
连接 → OB(Option Bytes)
→ Read Protection: Level 0 / Level 1 / Level 2
解除 Level 1 保护
方法一:STM32CubeProgrammer
-
连接芯片(如果通过 SWD 连不上,切换到 ISP 方式)
-
选 OB 标签
-
Read Protection 下拉选 Level 0(AA)
-
点 Apply
-
工具自动执行全片擦除并设置 RDP = AA
方法二:串口 ISP(FlyMCU)
进入 ISP 模式(BOOT0=1)→ 连接 → 点击"擦除芯片"→ 自动把 RDP 变回 Level 0。
代码中设置 RDP
void Enable_ReadProtection(void)
{
FLASH_OBProgramInitTypeDef ob = {0};
ob.OptionType = OPTIONBYTE_RDP; // 不同 HAL 版本可能使用 OB_OPT_RDP,以实际 stm32f4xx_hal_flash_ex.h 为准
ob.RDPLevel = OB_RDP_LEVEL_1; // 或 LEVEL_0 / LEVEL_2
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBProgram(&ob);
HAL_FLASH_OB_Launch(); // 生效(会复位芯片)
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}
注意:一旦设成 Level 2,永久锁定,没有任何办法解除! 不要在产品代码中写 Level 2。
其他常见的选项字节设置
// 设置 BOR(掉电复位)
// F407 默认 BOR 关闭,电压掉到 1.8V 才复位
// 可以在 CubeProgrammer 中设置 BOR Level,让芯片在 2.7V/2.4V/2.1V 时就复位
// 硬件看门狗
// 如果设了 WDG_SW(0=硬件启动看门狗,1=软件启动),芯片一上电看门狗就开始跑
// main 执行前就复位了——那就只能用 ISP 改回来了
警告
| 操作 | 后果 |
|---|---|
| 设置 RDP Level 2 | 永久锁定,芯片报废 |
| 乱改选项字节 | 可能芯片无法启动,必须用 ISP 全片擦除 |
| 设了硬件 IWDG | 上电就开始计时,初始化时间长一点就会反复复位 |
如果芯片彻底废了
如果 RDP Level 2 或者 Bootloader 被覆盖,这块芯片就是一次性的了。普通爱好者一般没有恢复手段(除非用高端工具移除 Flash 保护位)。
保险建议:
-
调试阶段不要设 RDP
-
量产时用 Level 1(防止读抄),但要留 ISP 擦除能力
-
永远不要用 Level 2