I am programming an ARM Cortex-R4 and I have a few binary files that I'd like to execute them from TCRAM, just to see if the increase in performance is good enough.
I know I'd have to write a function to copy the binaries to the RAM (which can be accomplished with the linker script, and knowing the size of the binaries). But how would they run?
Imagine this: The first binary has func1(), func2(), func3() and func4(). I'd copy the entire module to TCRAM and how would I call a function there? I'd have to use a function pointer to that specific function? And what if func4(), calls func2() and func3()? If I'm not mistaken they'd point to the piece of code located in the flash. Does that mean I'd have to re write those funcs? Use entirely function pointers? I've been told that just the linker script is enough to do all of this and I needn't worry about anything, but I still don't understand how it works.
You have two options.
pc relative
.A simple copy will only work if the routines do not use any absolute addresses. It maybe fine if they do use the absolute address as I guess you are going to leave a copy in standard RAM. However, this may not get the full benefit of the
TCM
.With a linker script, you can specify a different
LOAD
andRUN
locations.Note especially
AT>FLASH
.See also: gnu linker map file... and many more on stackoverflow. The Gnu Ld manual has information on
LMA
sections (LOAD address). YourLMA
would be flash, but theVMA
(RUN address) would be TCM. The manual link above also shows how to copy. TheRAM
,FLASH
, andTCM_MEM
are defined with ld MEMORY information, depending on the addresses are for your board. All of this will be documented in aMAP
file. Be sure to generate aMAP
file and examine the addresses to double check yourld
script.The 2nd case also requires a copy (at start-up or at least before the first
TCM
function use). However, the compiler can use absolute addresses and they will be in theTCM
memory. Also any function within the mainDRAM
can call theTCM
function directly. With the first case, you must use function pointers to call theTCM
code. If you wish global variables to be placed in this memory, you can use attributes to put them in different sections and use gnu ld to place them appropriately. I think there isITCM
andDTCM
? So maybe this doesn't apply for you, or you need two sections.The linker script is more generic and will work best if you put complicated functionality in the
TCM
. Just using-fpic
, etc and copying may get things working quickly, especially if you only have a singlepure
function.On GCC: Just put the function in the .data section:
It will be copied over with the rest of your initialzed variables by the startup code (no need to mess with the linker scipt). You may also need a "long_call" option as well if the function ends up "far away" from the rest of the code after being placed into RAM.
Example:
You may get an compiler warning that can be safely ignored:
Nowadays (then-a-days as well?) you can just use the macro
__RAM_FUNC
,__RAMFUNC_EXT(bank, name)
or__RAMFUNC(bank)