MADL!AR
Code is cheap, show me the PPT!
首页
分类
Fragment
关于
STM32将变量定义到指定RAM地址
分类:
硬件
发布于: 2024-01-07
本实验基于STM32CubeIDE,ST 推出的免费集成编译环境,基于 Eclipse 开源框架,集成了 GCC、GDB 等免费的编译器、链接器。需要对内存进行细分时,比如指定变量/函数/文件到特殊地址等等,可以通过“*.ld”链接文件来实现。 ld即Linked Script,ST官网有一个官方文档 LAT0816 用来简单介绍ld如何编写。使用IDE创建好功能之后,项目根目录有两个文件`STM32XXX_FLASH.ld` 和 `STM32XXX_RAM.ld`,我们需要修改的是前者,后者是在线调试时使用,修改后对编译的结果没有作用。 ld文件分`MEMORY`和`SECTIONS`两个章节,前者用来定义存储器的分段结构,后者可以视作一个逻辑层面的段,用来将变量标识到指定位置。 以下是STM32H753的`MEMORY`: ``` MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } ``` 上面为默认的配置,也可以对其进行分割、指定自定义的标识。可以指定一个段,用来将变量保存在D2区域: ``` .ram_d2 : { . = ALIGN(4); _ram_d2_start = .; *(.ram_d2) . = ALIGN(4); _ram_d2_end = .; } >RAM_D2 ``` 然后按如下定义变量: ``` __attribute__((section(".ram_d2"))) uint8_t key[8] = {}; ``` 同时,要__在IDE中清除掉之前编译的缓存__,否则修改不会生效。 观察build analyzer,变量已经分配到RAM D2区域: ![RAM区域](/notebook/publish/i/caoliang.net/img/88260817b9998b701fa2aaff27681d40.png) ### 未解决的问题 在某些时候,需要把变量指定到RAM的某位置,同时还带有初始值,在上面的示例里就没有体现。上述示例,变量不包含初始值。如果要这么做,就需要将变量编译到Flash里,在运行阶段,再加载到RAM_D2。LAT0816有介绍: > * VMA(the virtual memory address):这是运行输出文件时,该 section 的地址。VMA 是可选项,可以不设置。 * LMA(load memory address):这是加载 section 时的地址。 > 在大多数情况下,这两个地址是相同的。当然也可以不相等,比如下面的例子就是 LMA 和 VMA 不同的案例: 数据段被加载到 ROM 中,然后在程序启动时复制到 RAM 中(通常用于初始化全局变量)。此时 ROM 地址就是LMA,RAM 地址就是 VMA。 同时,其给出了一个示例: ``` /* Initialized data sections into "RAM" Ram type memory */ .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH ``` 即“.data”因为有“>RAM AT> FLASH”的修饰,表示`.data`段的 VMA 为 RAM,LMA 为 FLASH。即`.data` 段的内容会放在 FLASH 中,但是运行时,会加载到 RAM 中。 在RAM_D2的示例中,同样在定义结尾加上修饰符:`>RAM AT> FLASH`,在build analyzer窗口中观察到变量的LMA已经分配到flash,但烧录到MCU中测试,赋予的初始值并没有生效。 ![RAM区域2](/notebook/publish/i/caoliang.net/img/badfd8af385ece20f087f7d684704659.png) 经过反复折腾均告失败,由此先在这里打个记号吧,等后续解决之后再来更新。现阶段只能手动拷贝了。