我正在编写一个ARM Cortex-R4,我有一些二进制文件,我想从TCRAM执行它们,只是为了看看性能是否足够好。
我知道我必须编写一个函数来将二进制文件复制到RAM中(可以使用链接器脚本完成,并了解二进制文件的大小)。但他们怎么会跑?
想象一下:第一个二进制文件有func1(),func2(),func3()和func4()。我将整个模块复制到TCRAM,如何在那里调用函数?我必须使用指向该特定功能的函数指针?如果func4()调用func2()和func3()怎么办?如果我没弄错的话,他们会指向闪存中的代码片段。这是否意味着我必须重写那些功能?使用完全函数指针?我被告知只有链接器脚本足以完成所有这些,我不必担心任何事情,但我仍然不明白它是如何工作的。
答案 0 :(得分:10)
在GCC上:只需将该函数放入.data部分:
__attribute__( ( section(".data") ) )
它将通过启动代码复制其余的初始化变量(不需要乱用链接器scipt)。如果函数在放入RAM后最终“远离”其余代码,则可能还需要“long_call”选项。
__attribute__( ( long_call, section(".data") ) )
示例:
__attribute__( ( long_call, section(".data") ) ) void ram_foobar (void) { ... }
您可能会收到一个可以安全忽略的编译器警告:
Warning: ignoring changed section attributes for .data
答案 1 :(得分:6)
您有两种选择。
pc relative
进行编译。只有例程不使用任何绝对地址时,简单副本才有效。如果他们使用绝对地址可能会很好,因为我猜你要在标准RAM中留下副本。但是,这可能无法充分利用TCM
。
使用链接描述文件,您可以指定不同的LOAD
和RUN
位置。
sections {
.text { *(.text); } >FLASH
.tcm {
*(.tcm);
} >TCM_MEM AT>FLASH
.data { *(.data); } > RAM
.bss : NOLOAD { *(.bss); } > RAM
}
请特别注意AT>FLASH
。
另请参阅:gnu linker map file...以及 stackoverflow 上的更多内容。 Gnu Ld manual包含LMA
个部分的信息( LOAD 地址)。您的LMA
将 flash ,但VMA
( RUN 地址)将为 TCM 。上面的手动链接还显示了如何复制。 RAM
,FLASH
和TCM_MEM
定义为ld MEMORY信息,具体取决于您的电路板的地址。所有这些都将记录在MAP
文件中。请务必生成MAP
文件并检查地址,以便仔细检查ld
脚本。
第二种情况还需要一份副本(在启动时或至少在第一次使用TCM
功能之前)。但是,编译器可以使用绝对地址,它们将位于TCM
内存中。此外,主DRAM
中的任何函数都可以直接调用TCM
函数。对于第一种情况,您必须使用函数指针来调用TCM
代码。如果您希望将全局变量放在此内存中,可以使用属性将它们放在不同的部分中,并使用 gnu ld 将它们放置在适当的位置。我认为有ITCM
和DTCM
?所以这可能不适合你,或者你需要两个部分。
链接器脚本更通用,如果在TCM
中添加复杂功能,它将更有效。只需使用-fpic
等,复制就可以让事情快速发挥作用,特别是如果你只有一个pure
函数。
答案 2 :(得分:2)
现在(还是一天?),您可以只使用宏__RAM_FUNC
,__RAMFUNC_EXT(bank, name)
或__RAMFUNC(bank)