如何在ARM体系结构上从RAM运行代码

mor*_*llo 8 arm

我正在编程一个ARM Cortex-R4,我有一些二进制文件,我想从TCRAM执行它们,只是为了看看性能是否足够好.

我知道我必须编写一个函数来将二进制文件复制到RAM(可以使用链接器脚本完成,并且知道二进制文件的大小).但他们怎么会跑?

想象一下:第一个二进制文件有func1(),func2(),func3()和func4().我将整个模块复制到TCRAM,如何在那里调用函数?我必须使用指向该特定功能的函数指针?如果func4()调用func2()和func3()怎么办?如果我没弄错的话,他们会指向闪存中的代码片段.这是否意味着我必须重写那些功能?使用完全函数指针?我被告知只有链接器脚本足以完成所有这些,我不必担心任何事情,但我仍然不明白它是如何工作的.

小智 10

在GCC上:只需将函数放在.data部分:

__attribute__( ( section(".data") ) )
Run Code Online (Sandbox Code Playgroud)

它将通过启动代码与其余的初始化变量一起复制(不需要乱用链接器scipt).如果函数在放入RAM后最终"远离"其余代码,则可能还需要"long_call"选项.

__attribute__( ( long_call, section(".data") ) )
Run Code Online (Sandbox Code Playgroud)

例:

__attribute__( ( long_call, section(".data") ) ) void ram_foobar (void) { ... }
Run Code Online (Sandbox Code Playgroud)

您可能会收到可以安全忽略的编译器警告:

Warning: ignoring changed section attributes for .data
Run Code Online (Sandbox Code Playgroud)


art*_*ise 6

你有两个选择.

  1. 按照你的建议复制它们,编译pc relative.
  2. 使用具有不同加载/运行地址的链接器文件.

只有例程不使用任何绝对地址时,简单副本才有效.如果他们确实使用绝对地址可能没问题,因为我猜你要在标准RAM中留下副本.但是,这可能无法充分发挥作用TCM.

使用链接描述文件,您可以指定其他位置LOADRUN位置.

sections {
 .text { *(.text); } >FLASH
 .tcm {
       *(.tcm);
  } >TCM_MEM AT>FLASH
  .data { *(.data); } > RAM
  .bss : NOLOAD { *(.bss); } > RAM
}
Run Code Online (Sandbox Code Playgroud)

请特别注意AT>FLASH.

另请参阅:gnu链接器映射文件...以及stackoverflow上的更多内容.所述的Gnu Ld的手册有信息LMA的部分(LOAD地址).你LMA闪现,但VMA(运行地址)将是TCM.上面的手动链接还显示了如何复制.的RAM,FLASH以及TCM_MEM与LD定义MEMORY信息,根据地址是您的主板.所有这些都将记录在一个MAP文件中.确保生成MAP文件并检查地址以仔细检查ld脚本.

第二种情况也需要一份副本(在启动时或至少在第一次TCM使用功能之前).但是,编译器可以使用绝对地址,它们将在TCM内存中.此外,main中的任何函数都DRAM可以TCM直接调用该函数.对于第一种情况,您必须使用函数指针来调用TCM代码.如果希望将全局变量放在此内存中,可以使用属性将它们放在不同的部分中,并使用gnu ld将它们放置在适当的位置.我觉得有ITCMDTCM?所以这可能不适合你,或者你需要两个部分.

链接器脚本更通用,如果您将复杂的功能放在中,它将最有效TCM.只需使用-fpic等,复制可以使事情快速pure发挥作用,特别是如果你只有一个功能.