我想在stm32中保存一块闪存来存储我自己的配置信息。
为此,我想将闪存的第二个扇区保存在 STM32F2/STM32F4 上(16kb 存储在 0x08004000-0x08007FFF)
检查互联网和 stackoverflow,你有 4 种方法可以做到这一点
1)
#pragma location=0x08004000
__no_init const char ReservedArea[16*1024];
2)
__no_init const char ReservedArea[16*1024] @0x08004000;
3) 创建一个部分 + #pragma location=
项目icf:
place at address mem: 0x08004000 { readonly section ConfigSection };
c文件:
#pragma location="ConfigSection"
__no_init const char ReservedArea[16*1024];
4)
在项目 .icf 文件中定义一个部分IAR 定义自定义数据的内存区域
发现错误或问题
方法 1 到 3工作正常。链接器为我的变量包含一个空间区域。您可以检查使用十六进制编辑器生成的 .bin 文件,或者仅调试并查看该变量为 @ 0x08004000。
使用这些方法发现的问题是 iar 链接器在 0x08000800 - 0x08003FFF 之间留下了超过 12kbytes 的未使用闪存。验证这一点的最佳方法是删除 var,编译,在注释中写入 bin 文件的大小,然后添加变量。如果你这样做,你会注意到新的 bin 文件大小大于 16kb,而它必须是 16kb。
如果您将地址从 0x08004000 移动到 0x0800C000 而不进行任何其他更改,则文件大小将再增加 32kbytes,并且所有先前的区域都设置为 0x00,并且在 bin 文件中未使用。这对我们的项目来说是一个大问题,因为我使用 bin 文件中剩余的未使用区域来允许固件更新。
检查地图文件,您会发现保留区之前的区域也未使用。
我尝试了几种方法来解决这个问题,例如定义 2 个带地址的变量、玩几个小时、检查链接器选项、优化、使用其他 #pragma 选项等。
关于第四种方法,它将变量存储在系统中,但它没有得到我想要的地址。问题可能是两个区域共享地址空间。
.icf 文件
define region LANGUAGE_region = mem:[from 0x08004000 to 0x08007FFF];
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
"LANGUAGE_PLACE":place at start of LANGUAGE_region { section .LANGUAGE_PLACE.noinit };
c代码
extern const char ReservedArea[16*1024] @".LANGUAGE_PLACE.noinit";
const char ReservedArea[16*1024];
是我的问题吗?这是一个错误吗?欢迎任何提示。
提前致谢。