如何通过代码实现STM32F407 Flash扇区11的写保护?
如何通过代码实现STM32F407指定Flash扇区的写保护
问题背景
你在STM32F407上首次烧录后向Flash扇区11写入序列号,但偶尔出现数据丢失(读取值为0xFFFFFFFF),手动通过STM32CubeProgrammer开启该扇区写保护后问题解决,需要通过代码自动实现这一操作。
原理说明
STM32F407的Flash写保护依赖**选项字节(Option Bytes)**中的WRP(Write Protection)配置。每个WRP寄存器对应一组扇区,配置后Flash控制器会阻止对受保护扇区的擦除和写入操作。扇区11属于WRP区域1(覆盖扇区8-11),通过编程选项字节可单独开启该扇区的写保护。
代码实现
以下是通过HAL库实现扇区11写保护的完整函数:
#include "stm32f4xx_hal.h" void FLASH_Enable_Sector11_WriteProtection(void) { FLASH_OBProgramInitTypeDef ob_config = {0}; // 1. 解锁Flash及选项字节(选项字节操作必须先解锁) HAL_FLASH_Unlock(); if (HAL_FLASH_OB_Unlock() != HAL_OK) { printf("OB Unlock Failed\n"); goto cleanup; } // 2. 获取当前选项字节配置,避免重复操作 HAL_FLASHEx_OBGetConfig(&ob_config); if ((ob_config.WRPSector & OB_WRP_SECTOR_11) == OB_WRP_SECTOR_11) { printf("Sector 11 already write protected\n"); goto cleanup; } // 3. 配置写保护参数 ob_config.OptionType = OPTIONBYTE_WRP; ob_config.WRPState = OB_WRPSTATE_ENABLE; ob_config.WRPSector = OB_WRP_SECTOR_11; // 仅保护扇区11 // 4. 编程选项字节 if (HAL_FLASHEx_OBProgram(&ob_config) != HAL_OK) { printf("OB Program Failed\n"); goto cleanup; } // 5. 加载新选项字节(触发系统复位,配置生效) HAL_FLASH_OB_Launch(); cleanup: // 6. 锁定选项字节及Flash HAL_FLASH_OB_Lock(); HAL_FLASH_Lock(); }
关键注意事项
- 执行时机:必须在完成扇区11的重要数据写入(即你的
FLASH_write_serial_number函数执行成功后)再调用此函数,一旦开启写保护,该扇区将无法再被擦除或写入,除非重新解锁选项字节并清除WRP配置。 - 复位生效:调用
HAL_FLASH_OB_Launch()会触发系统自动复位,新的写保护配置在复位后生效。 - 临界区保护:如果在RTOS环境下操作,建议像你的写入函数一样,用
taskENTER_CRITICAL()和taskEXIT_CRITICAL()包裹整个操作,避免中断干扰选项字节编程。 - 扇区对应关系:确认
OB_WRP_SECTOR_11宏的正确性,该宏定义于stm32f4xx_hal_flash_ex.h,对应STM32F407的扇区11。
集成建议
修改你的写入流程,确保写入成功后自动开启保护:
void Write_Serial_And_Protect(uint32_t your_serial_number) { taskENTER_CRITICAL(); // 写入序列号 FLASH_write_serial_number(your_serial_number); // 开启扇区11写保护 FLASH_Enable_Sector11_WriteProtection(); taskEXIT_CRITICAL(); }
内容的提问来源于stack exchange,提问作者TheBestPlayer
相关产品推荐
相关产品推荐

