01、概述
在实际项目中,经常有这样的需求,希望把变量、函数,甚至是文件,存放到指定的内存上,那么在STM32CubeIDE中应该如何实现呢?
02、示例
刚好手中有一块NUCLEO-G474RE的开发板,STM32G474拥有128K Bytes的RAM,512K Bytes的Flash。
在STM32CubeIDE中,由链接文件linker file(*.ld)来决定内存的分布,也就是工程师们常说的内存分散加载文件。
2.1. 指定变量地址
目标:自定义变量运行时位于0x20010000开始的64KB的RAM内存中,编译后的数据初始值存储在0x08010000开始的448KB的FLASH内存中。
为了实现这一目标,我们要先在链接文件中,划分出这片RAM内存(如取名为MY_RAM)和FLASH内存(如取名为MY_FLASH,红色为增加的内容):

MY_RAM:起始地址0x20010000;大小:64K;权限:x(可执行)、r(可读)、w(可写),即作为可读写的内存使用。
MY_FLASH:起始地址0x08010000;大小:448K;权限:r(可读)、x(可执行),不可写(FLASH特性),用于存储程序代码。
然后进行段的分配(黄色为增加的内容):


注意:链接文件的Section定义中,”.my_code_section”需要放在“.text”之前。
因RAM的特性,上电之后其内容是随机值,所以在使用RAM之前强烈推荐先初始化为默认值(如0x00)。
下面代码就是初始化MY_RAM的示例(黄色为增加的内容):


如此一来,我们就完成了内存的布局,接下来,只要在做应用层的申明/定义时,带上内存的属性就可以了。
/* Private variables ---------------------------------------------------------*/
COM_InitTypeDef BspCOMInit __attribute__((section(".mydata.my_variables")));如上述示例的“BspCOMInit”结构体变量,通过
“__attribute__((section(".mydata.my_variables")))”修饰,就会存放在MY_RAM内存域。
编译之后,可通过map文件来验证结果:

▲ 图1. 指定变量位置
2.2. 指定函数地址
在文件中,通过attribute属性来修饰函数,对于多个函数,申明的顺序就是函数存放在memory中的顺序:
void My_Func_1(void) __attribute__((section(".my_section.My_Func_1")));
void My_Func_3(void) __attribute__((section(".my_section.My_Func_3")));
void My_Func_2(void) __attribute__((section(".my_section.My_Func_2")));2.3. 指定文件地址
将“main.c”和“sysmem.c”两个文件指定存放在“MY_FLASH(0x08010000)”内存域中,可这样来实现:“./Application/User/Core/main.o(.text .text*)”,“./Application/User/Core/ sysmem.o(.text .text*)”。
完整参考如下所示(黄色粗体部分):

注意这里的文件路径是STM32CubeIDE中的项目路径,不是电脑中文件夹的路径。

▲ 图2. 本示例中的文件
编译之后,查看map文件可验证结果,能看到函数的地址和顺序,以及文件的地址都是在0x08010000之后了:

▲ 图3. 指定函数/文件的内存
03、小结
本文实验完整的实验工程(点击下载)供大家直接使用,希望对大家有所帮助。
来源:STM32
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。