Placing and executing a function in RAM

I’m working on a helicopter autopilot using a SAM7S256. I really haven’t got into the real stuff yet, but I found that the execution speed when running from flash never can exceed 30 MHz in ARM-mode. Therefore my plan is to put the computation intensive functions in RAM instead.

I’m working with Eclipse and GNU-tools.

Unfortunately all attempts have failed. I have tried to define a function with attribute placing it in the .data-section (and enabling long-jumps), but I just can’t get it to work.

I want the function to be programmed in flash, copied to RAM on startup (just as the variables) and then executed from RAM whenever it’s called.

Can someone please help me out here?

May be this could help. Never tryed myself.

http://www.siwawi.arubi.uni-kl.de/avr_p … cc_ramfunc

Angelo

Thanks for your reply. However, I can’t find any fundamental differences between this example and my own code. Probably it’s some detail I’m missing and I can’t just copy the entire example as I’m running an entirely different MCU.

If you have got this to work with WinARM and SAM7 please tell me how to do it.

Here’s how I managed to place a function into RAM and have it automatically copied at boot-up.

The GNU compiler allows you to place a function into its own section.

Let’s assume that we want to create a C function called calculate.c and that this function should be loaded and executed from RAM memory. The trick is to put the RAM-based function into its own section called .ram-func as shown below.

long calculate(long a, long b) attribute ((section (“.ram_func”)));
long calculate(long a, long b) {
long c;
c = a * b;
return c;
}

Here is the calculate function being called from the main program.

#include “AT91SAM7S256.h”
extern long calculate(long, long);
int main (void) {
** static long t = 0; // variable for RAM function test**
** static long u = 0; // variable for RAM function test**
** static long v = 0; // variable for RAM function test**
** t = 0;**
** u = 15;**
** v = 27;**
** t = calculate(u, v); // this function executed from RAM**
}

Since the calculate( ) function was compiled into a specific section called .ram_func then the linker script should place this section into the RAM memory part. Note that a copy of the RAM function is also placed into the initializer part of flash and will be copied to RAM at boot-up.

/* demo_at91sam7_blink_flash.cmd LINKER SCRIPT /
ENTRY(_vec_reset)
__/
specify the AT91SAM7S256 memory areas /__
MEMORY
{
** flash : ORIGIN = 0, LENGTH = 256K **
** ram : ORIGIN = 0x00200000, LENGTH = 64K
*
}
_stack_end = 0x20FFFC;
/* now define the output sections */
SECTIONS
{
** . = 0; **

** .text : **
** {**
__ (.text) __
__ (.rodata)__
__ (.rodata) __
(.glue_7)
(.glue_7t)
** _etext = .;

** } >flash **
** .data : **
** {

** _data = .; **
__ (.data) __
(.ram_func)
** _edata = .; **
** } >ram AT >flash

** .bss : **
** {**
** _bss_start = .; **
__ *(.bss) __
** } >ram **
** . = ALIGN(4); **
** _bss_end = . ; **
}
** _end = .; **

Do the SAMs have the equivalent of the NXP LPC21xx “MAM”, flash accellerator? This does a 128 bit read from flash, times two concurrently, then feeds the instruction pipeline. There’s a MAM-enable register/mode in the LPC21xx - perhaps similar in the SAMs?

Net result, they say, is that the CPU has no wait states for flash access. At least for instructions - constant data in flash might be handled differently.

No, unfortunately the SAM7-architecture does not have anything like the MAM.

However, as the chip has plenty of RAM, in my case most time-consuming functions will fit in there without a doubt.

I got the RAM-run stuff working now by the way. I’m still not sure what the problem was, but I used a different example and modified it. Thanks for the help anyway.