HOWTO: Run a routine from RAM in S32 Design Studio

Document created by stanish Employee on Mar 23, 2017
Version 1Show Document
  • View in full screen mode

This document describes a way how to execute a selected function(s) out of RAM memory for a project running out of  Flash memory.

 

  • Create a custom linker section in the linker file (.ld) where a routine(s) should be placed into. This step is optional if you don't care where exactly in RAM the function should be placed. In such case default sections could be used instead.
    MEMORY
    {
     
        flash_rchw : org = 0x00FA0000,   len = 0x4
        cpu0_reset_vec : org = 0x00FA0000+0x10,   len = 0x4
        cpu1_reset_vec : org = 0x00FA0000+0x14,   len = 0x4
        cpu2_reset_vec : org = 0x00FA0000+0x04,   len = 0x4     
           
        m_my_flash :     org = 0x01000000, len = 4K       // optional - this is dedicated section for the RAM function rom image
        m_text :         org = 0x01001000, len = 5628K    // default section for code
     
        m_my_ram :       org = 0x40000000, len = 4K       // optional - specific section where a RAM routine(s) should be copied into
        m_data :         org = 0x40001000,  len = 764K    // default section for data/stack/heap
    }
    • If it's intended to keep routine(s) that should be executed from RAM within a specific custom section:
SECTIONS
{
...
.MyRamCode :
{
   MY_RAM_START = .;       // this symbol is optional
   KEEP (*(.MyRamCode))    // KEEP - avoid dead stripping if an object is not referenced
   MY_RAM_END = .;         // this symbol is optional
} > m_my_ram AT>m_my_flash // the section above is linked into m_my_ram and Rom image is stored into m_my_flash

 

  • Otherwise you can use the default memory areas for code/data if you don't care about the location of the routine(s):
SECTIONS
{
...
.MyRamCode  :
{
    MY_RAM_START = .;     // this symbol are optional
    KEEP (*(.MyRamCode))  // KEEP - avoid dead stripping if an object is not referenced
    MY_RAM_END = .;       // this symbol are optional
}  > m_data  AT>m_text    // the section is linked into default data memory area and its rom image is placed into the default code memory

 

  • add the __attribute__ statements to the RAM function prototypes. The function attribute "longcall" is required to be able to call this RAM function from flash.
__attribute__ ((section(".MyRamCode")))              // place the function below into .MyRamCode section
int test_RAM(int arg1) __attribute__ ((longcall));   // declare the function as "far"
  • Default S32DS project startup initializes just the default data sections. Therefore it's necessary to perform section copy-down manually if the functions are placed into a custom section. This must be done before a RAM routine gets called e.g. at the beginning of main() or in the startup routine.

      You can create some linker symbols (.MyRamCode RAM and ROM addresses and size) and import them to the module where copy-down is implemented.

 

__MY_RAM_ADR = ADDR (.MyRamCode);
__MY_RAM_SIZE = SIZEOF (.MyRamCode);
__MY_RAM_ROM_ADR = LOADADDR (.MyRamCode);

 

The final source file may look like this:

#include <string.h>
extern unsigned long __MY_RAM_ADR;
extern unsigned long __MY_RAM_ROM_ADR;
extern unsigned long __MY_RAM_SIZE;

__attribute__ ((section(".MyRamCode")))              // place the function below into .MyRamCode section
int test_RAM(int arg1) __attribute__ ((longcall));   // declare the function as "far"
...

void main(void)
{
   int counter = 0;
   memcpy(&__MY_RAM_ADR , &__MY_RAM_ROM_ADR, &__MY_RAM_SIZE);  // copy the function from flash to RAM
   counter = test_RAM(counter);                                // call the function
...
}

 

Hope it helps!

Stan

2 people found this helpful

Attachments

    Outcomes