Run your Code in RAM, speed up your work

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Run your Code in RAM, speed up your work

1,477 Views
peter_vranken
Contributor IV

Dear MPC Users,

 

I'd like to share a snippet from my linker script with you - a snippet which I really love. Using the proposed construct, you can decide on-the-fly under control of your Makefile or S32 Design Studio Build Configuration, whether to flash the compiled SW or to load, run and debug it from RAM. Most likely, nothing needs to be modified in the built SW, i.e. in source or library file. (We use the MPU and require a preprocessor #if/#else in its configuration; similarly, there's a switch in the MMU configuration of the MPC5775.)

 

Meanwhile, flashing SW under development became really rare. Most of the time, I build it for RAM and run it via the Eclipse launch button to inspect and debug it. That's significantly faster than flashing the SW and it safes erase-and-flash cycles for the MCU.

 

The linker script code has been made for the MPC5748G and is modifiable for many or most other MPCs. The only relevant limitation is that it will simply not pay off for those derivatives, which have only little RAM. Moreover, since code and data need to fit into RAM, even the biggest MPCs won't probably be capable to run your complete, elaborated SW this way, but think about development and testing of units/subcomponents of it.

 

Here's the snippet. The only trick is to set the memory segments not according to the physical memories, but all of them to portions of the RAM:

 

    /* We use the simple conditional operator the linker script syntax

       offers for switching from normal build of a flashable binary to an

       equivalent binary that can be loaded into RAM by the debugger.

       Using RAM can have these advantages:

       - We save flash ROM programming cycles, which are limited

       - It reduces the turnaround time between code changes. Loading RAM

         is faster than erasing and re-flashing

       - The risk of bricking the CPU is lower if we work on code, which

         is critical in this respect; e.g. self-tests, security, reset

         logic, reset escalation

       The major drawback is the software size; code and data need to fit

       into RAM. We use a hard-coded distribution of both, 67% for code,

       33% for data.

         Note, the switch ld_linkInRAM is set by the makefile using the

       linker command line option --defsym. */

    ld_textSegStartAddr = ld_linkInRAM==1? 0x40000000 : 0x00f90000;

    ld_textSegSize      = ld_linkInRAM==1? 2*256k : 0x01580000 - 0x00f90000;

    ld_dataSegStartAddr = ld_linkInRAM==1? ld_textSegStartAddr + ld_textSegSize : 0x40000000;

    ld_dataSegSize      = ld_linkInRAM==1? 3*256k - ld_textSegSize : 3*256k ;

 

 

    /* Definition of memory regions using absolute addresses of physical

       memories. */

    MEMORY

    {

        /* RM, sec. 3.2: f8c000 is the first inspected boot sector.

           However, this area is marked "Small HSM Code Block". According

           to RM, 3.3, table 3-2, f90000 is the beginning of the generally

           usable flash ROM and it's at the same time the second boot

           sector. */

        memBoot(rx):  org = ld_textSegStartAddr, len = 0x18

        memFlash(rx): org = ld_textSegStartAddr + LENGTH(memBoot),

                            len = ld_textSegSize - LENGTH(memBoot)

        memData(rwx): org = ld_dataSegStartAddr, len = ld_dataSegSize

    }

 

You will easily find the block

 

    MEMORY

    {

    ...

    }

 

in your linker script and it'll be structural same. The details will differ a bit. You will see the similarities and understand, how to adapt the code snippet to meet the details of your particular linker script.

After modifying the linker script, you need to do two more things:

 

At first, copy an existing Build Configuration in Eclipse and modify it in a way that makes the modifications take effect. Several possible ways exist: Using the command line or setting an environment variable for an External Builder, using the linker settings for the Internal Builder, making a copy of the linker script and use original and modified either/or ... In the sketch, a linker symbol is set from outside using the linker command line switch "--defsym ld_linkInRAM".

 

At the same time, the copied build configuration should be configured to produce the loadable binaries either in another folder or with another name.

 

Secondary, the Launch Configuration is copied, too. Change the path/filename of the *.elf file to use. The check-box "Load executable" on tab "Startup" needs to be checked. ("Load symbols" anyway.) This makes the debugger put your compiled code and data into RAM so that it can be run there, regardless of what's currently flashed. All other settings stay as usual. Start the SW in RAM by launching the altered configuration.

 

If built for RAM, the SW can be started only in and with help of the debugger. Once started, you can disconnect the debugger and it'll continue running. Hence, long-running tests are possible this way, too.

 

After next reset, your board will start up again with the currently flashed SW.

Labels (1)
0 Replies