如何将STM32F4的结构体数组放置在备份RAM指定起始地址
STM32F4将结构体数组固定到备份RAM起始地址的实现方法
共有两种常用的实现方案,都可以满足你的需求:
方案1:直接地址映射(最简单,无需修改链接脚本)
直接将备份RAM的起始地址强制转换为你的结构体数组指针,代码如下:
// 直接定义foos指向BKPSRAM_BASE地址 #define foos ((Foo *) BKPSRAM_BASE)
这个方案的优势是不需要修改任何编译配置,数组天然对齐到备份RAM的起始地址,也不会占用常规RAM的存储空间。
方案2:编译器段指定+链接脚本配置(适合多变量存放在备份RAM的场景)
- 首先在定义变量时,用编译器属性指定将数组放到自定义段:
// GCC编译器写法,其他编译器对应修改段指定关键字即可 Foo foos[40] __attribute__((section(".bkpsram")));
- 修改项目的链接脚本(.ld后缀文件),首先在
MEMORY块中添加备份RAM的区域定义:
MEMORY { /* 原有其他存储区域定义,例如FLASH、SRAM等 */ BKPSRAM (xrw) : ORIGIN = 0x40024000, LENGTH = 4K /* 0x40024000就是STM32F4的BKPSRAM_BASE实际值 */ }
- 在
SECTIONS块中添加自定义段的映射规则,将.bkpsram段放到备份RAM区域的起始位置:
SECTIONS { /* 原有其他段定义 */ .bkpsram (NOLOAD) : { *(.bkpsram) } > BKPSRAM }
注意添加
NOLOAD属性,避免上电时C运行时库自动清空或初始化备份RAM中的数据,导致掉电保存的内容丢失。如果只有foos一个变量放在.bkpsram段,就可以保证数组刚好对齐到备份RAM的起始地址。
必要前置配置(两种方案都需要配置)
要让备份RAM的数据在重启/主电源掉电(需VBAT接备用电池)后保留,必须在代码中开启对应权限和时钟:
// 1. 开启PWR时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // 2. 使能备份域访问权限 PWR_BackupAccessCmd(ENABLE); // 3. 开启备份RAM时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
额外注意事项
- 如果不需要主电源掉电时保留数据,仅看门狗/软重启保留,可以不用接VBAT备用电池
- 建议给Foo结构体添加对齐属性,避免不同编译器优化导致的结构体大小/成员偏移不一致问题:
typedef struct { // 结构体成员 } __attribute__((packed)) Foo;
内容的提问来源于stack exchange,提问作者Zhiyong Li
相关产品推荐
相关产品推荐

