我正在编程一个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)
你有两个选择.
pc relative.只有例程不使用任何绝对地址时,简单副本才有效.如果他们确实使用绝对地址可能没问题,因为我猜你要在标准RAM中留下副本.但是,这可能无法充分发挥作用TCM.
使用链接描述文件,您可以指定其他位置LOAD和RUN位置.
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将它们放置在适当的位置.我觉得有ITCM和DTCM?所以这可能不适合你,或者你需要两个部分.
链接器脚本更通用,如果您将复杂的功能放在中,它将最有效TCM.只需使用-fpic等,复制可以使事情快速pure发挥作用,特别是如果你只有一个功能.