目录
1. 简述
在嵌入式开发里代码存储的最原始位置一定是在断电不丢失的存储器上比如flash.
一般情况下MCU上程序运行时也是寻址flash上的代码(这个和linux/windows机制有所不同)
但是在某些情况下需要将flash上的代码拷贝到内存里执行(比如在bootloader里或者一些需要高效率执行的代码)。
本文将以NXP574xG MCU为例子 简述将代码放到ram上运行的方法:
2. 将代码放到ram上运行的方法及原理
2.1 在默认的连接文件MPC5745B_flash.ld里 已经写好了一个.code_ram section,在用户代码里有需要在ram上运行的函数 直接用该section 标注即可。
__CODE_ROM = __DATA_END ;/*+0x500 to avoid .got2 section conflict */
.code : AT(__CODE_ROM) /**/
{
. = ALIGN(4);
__CODE_RAM = .;
__code_start__ = .; /* Create a global symbol at code start. */
*(.code_ram) /* Custom section for storing code in RAM */
. = ALIGN(4);
__code_end__ = .; /* Define a global symbol at code end. */
} > m_data
__CODE_END = __CODE_ROM + (__code_end__ - __code_start__);
2.2 在需要拷贝到ram上运行的函数定义里添加属性__attribute__((section (".code_ram")))
void __attribute__((section (".code_ram"))) flashToRamfun()
{
sum++;
}
2.3 编译之后从生成的map文件里可以看到flashToRamfun的寻址地址变成了一个内存地址0x40000420但是其实际的存储位置还是在flash上0x010059d8
.code 0x40000420 0x28 load address 0x010059d8
0x40000420 . = ALIGN (0x4)
0x40000420 __CODE_RAM = .
0x40000420 code_start = .
*(.code_ram)
.code_ram 0x40000420 0x28 ./Sources/main.o
0x40000420 flashToRamfun
0x40000448 . = ALIGN (0x4)
0x40000448 code_end = .
0x01005a00 __CODE_END = (__CODE_ROM + (code_end - code_start))
2.4 在进入main函数前会先调用下面函数做段的初始化操作,在这里面会把code_ram段的代码从flash位置拷贝到ram 空间。这样程序运行的时候就可以通过内存地址访问到真实的代码指令了。
void init_data_bss(void)
{
..............
/* Copy functions from ROM to RAM */
while (code_rom_end != code_rom)
{
*code_ram = *code_rom;
code_ram++;
code_rom++;
}