将配置数据存储至Flash内存:烧录程序后数据丢失问题求助
解决Flash烧录时保留配置数据的方案
核心思路
问题根源是烧录工具默认执行全片擦除,要解决这个问题,核心是让烧录操作仅针对程序分区,跳过配置数据所在的独立分区,同时确保代码里的Flash读写逻辑严格限定在配置分区范围内。
具体实现步骤
1. 固化分区表的独立性
- 确保你的Flash分区表明确拆分出程序分区和配置数据分区,两个分区的地址范围完全不重叠。举个STM32的示例:
- 程序分区:
0x08000000-0x0803FFFF(128KB) - 配置分区:
0x08040000-0x0804FFFF(64KB)
- 程序分区:
- 把分区表信息嵌入项目的链接脚本或烧录配置文件,让编译器和烧录工具都能识别分区边界。
2. 修改烧录工具的擦写规则
不同工具的配置方式不同,以下是常见场景的操作:
- STM32CubeProgrammer:选择
Erase sectors而非Erase full chip,手动指定只擦除程序分区对应的扇区;或者直接导入自定义分区表,工具会自动跳过非程序分区。 - OpenOCD:在烧录脚本中用
flash write_image erase命令时,明确指定程序镜像的起始地址和大小,不覆盖配置分区。示例命令:
其中flash write_image erase your_program.elf 0x08000000 0x400000x40000是程序分区的大小(256KB),刚好截止到配置分区起始地址前。 - J-Link Commander:使用
loadfile命令时限定地址范围,避免擦除配置分区:loadfile your_program.bin 0x08000000 0x40000
3. 代码中严格锁定Flash操作范围
- 读写配置数据时,硬编码配置分区的起始地址和大小,绝对不触碰程序分区的地址空间。示例代码:
#define CONFIG_FLASH_START_ADDR 0x08040000 #define CONFIG_FLASH_SIZE 0x10000 // 64KB // 写入配置数据示例 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, CONFIG_FLASH_START_ADDR, config_data); - 禁止使用全片擦除API,比如
HAL_FLASH_Erase(FLASH_TYPEERASE_MASSERASE, ...),只擦除配置分区对应的扇区。
4. 验证数据保留效果
- 烧录前先往配置分区写入测试数据,烧录程序后读取该地址的数据,确认是否与烧录前一致。
- 如果数据仍被擦除,检查烧录工具的日志,确认是否存在“全片擦除”的操作记录,排查配置是否生效。
额外注意事项
- 若使用自定义Bootloader,要确保Bootloader的升级流程也跳过配置分区,避免Bootloader升级时误擦除数据。
- 配置分区的大小要根据实际需求设置,预留足够空间的同时不浪费Flash资源。
内容的提问来源于stack exchange,提问作者user3676500
相关产品推荐
相关产品推荐

