STM32L451 HAL闪存擦除失败,返回HAL_FLASH_ERROR_PGS错误求助
排查STM32L451闪存擦除HAL_FLASH_ERROR_PGS错误的思路
针对你遇到的最后一页闪存擦除失败(错误码HAL_FLASH_ERROR_PGS)、同代码在Bootloader中正常运行的问题,从以下几个方向逐一排查:
1. 检查选项字节(OB)的写保护配置
Bootloader和应用程序的选项字节配置可能存在差异,STM32L4的最后一页很可能被设置了写保护(WRP):
- 用STM32CubeProgrammer连接芯片,读取选项字节中的WRP区域,确认第255页是否被包含在写保护范围内。
- 如果存在写保护,需要在应用程序中先修改WRP配置(修改OB需先解锁,且修改后需复位生效),或者在Bootloader中预先配置好允许应用程序擦除该页。
2. 排查内存访问冲突
应用程序运行时,可能有其他代码或外设正在访问目标闪存页,导致擦除序列错误:
- 检查链接脚本中定义的独立段是否被误用作其他用途(比如存放全局变量、中断向量等),擦除时如果有CPU或DMA访问该区域会触发PGS错误。
- 确认擦除操作执行期间,没有中断服务程序、后台任务读取或写入该闪存页。可以在擦除前临时关闭相关中断,完成后再恢复。
3. 验证页地址与页号计算正确性
STM32L451的FLASH页大小需根据芯片容量确认,若页大小定义错误会导致页号计算偏差:
- 查STM32L451 datasheet:512KB容量的芯片,FLASH为256页×2KB,第255页的起始地址应为
0x08000000 + 255×2048 = 0x0807FC00,而你传入的地址是0x0807F800(对应第254页),需确认链接脚本定义的地址是否正确。 - 检查代码中
FLASH_PAGE_SIZE宏的定义是否与芯片实际页大小一致,避免页号或页数量计算错误。
4. 协程调度导致的解锁时机问题
你的代码使用了Protothreads协程,需确认PT_WAIT_UNTIL是否正确等待解锁完成:
- 排查协程调度逻辑,确保
HAL_FLASH_Unlock()和HAL_FLASH_OB_Unlock()返回HAL_OK后才执行擦除操作。可以在解锁后添加日志或断点验证状态。 - 尝试在非协程环境下直接调用擦除逻辑,排除协程调度带来的时序问题。
5. 电源电压稳定性检查
FLASH擦除操作对电源电压有要求(STM32L4要求VDD≥2.0V):
- 对比Bootloader和应用程序运行时的电源电压,应用程序可能因外设负载导致电压波动,达不到FLASH操作的阈值。可以在擦除前检测电源电压,满足条件后再执行操作。
内容的提问来源于stack exchange,提问作者bluscape
相关产品推荐
相关产品推荐

