Copy and execute code from RAM

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

Copy and execute code from RAM

3,003 Views
johndemayor
Contributor I

Hello,

I'm working with the KL17Z64.

I want to run code from RAM without touching the linker file. I'm very new in this area. The reason I don't want to change the linker file is because this RAM function will only be called in rare conditions - so I want to save resources and not allocate any memory by default. In the future I plan to use calloc() and free() for memory management but in the code below I've used a non-dynamic array (ramSpace[100]).

I have looked at most forum posts regarding executing code from RAM, but I run into hard-fault issues and still have some questions;

1. Is it at all possible to run code from RAM (copied from FLASH) without adapting the linker file?

2. I've setup a sample project to try to copy a function to RAM, created a function pointer to the RAM location, changed the LSB of the address such that the mode is changed (saw that in this post: ) and then executed the RAM function. Note that I have not changed the linker file at all.

void ATO_RomFunc(void){

  while(1){

  __asm("NOP");

  }

}

int main(void) {

  uint8_t ramSpace[100];

  void (*ramFunction)(void);

  /* Init board hardware. */

  BOARD_InitPins();

  // RAM test

  memcpy(ramSpace, ATO_RomFunc, 100); //Don't care for now if more code is copied than needed

  __disable_irq();

  ramFunction = (void (*)(void))ramSpace;

  ramFunction++; // Add 1 address for thumb

  ramFunction();

}

I see that in the disassembly:

62                   ramFunction();

00003fa4: 0x0000fb22   movs r2, #251   ; 0xfb

00003fa6: 0x00009200   lsls r2, r2, #2

00003fa8: 0x0000d219   adds r2, r2, r7

00003faa: 0x00001368   ldr r3, [r2, #0]

00003fac: 0x00009847   blx r3

Where r3 has content 0x20002c0d: which lies inside the SRAM block of the memory map. So I conclude that at least the function pointer part works. Is this assumption correct? However, after the branch (blx command), the C debugger stops and the disassembly jumps to the following code:

20002c0c: 0x0000b500   lsls r5, r6, #2

20002c0e: 0x0000afc0   stmia r0!, {r0, r1, r2, r3, r5, r7}

20002c10: 0x46fde780   stc2l 0, cr8, [r6, #-924]       ; 0xfffffc64

20002c14: 0x0000b516   asrs r5, r6, #26

20002c16: 0x00004fbd   pop {r0, r1, r2, r3, r6, pc}

20002c18: 0x00004400   lsls r4, r0, #1

20002c1a: 0x0000af00   lsls r7, r5, #2

20002c1c: 0x0000f0c8   ldmia r0!, {r4, r5, r6, r7}

20002c1e: 0x0000fc14   asrs r4, r7, #19

20002c20: 0x00004b18   adds r3, r1, r1

20002c22: 0x00001c04   lsls r4, r3, #16

20002c24: 0x00002101   lsls r1, r4, #4

20002c26: 0x22fff7d0   vqadd.u32 <illegal reg q6.5>, q9, <illegal reg q11.5>

I can continue to step through it in instruction mode but it's leading to a hard-fault at the last line (0x20002c26). What is it doing here, and why? I expected it to loop indefinately.

3. How can I set a breakpoint / debug the code running in RAM except for the hard-to-read disassembly?

Can anyone help me get any further? Any help is appreciated,

Best regards, John

Labels (1)
0 Kudos
3 Replies

1,473 Views
egoodii
Senior Contributor III

See also:

how to load function in flash while execute in ram

Make sure you copy enough code (it certainly looks like your last instruction is 'off in the weeds!), AND include 'compiler stored 32 bit constants' beyond the end of the code module.  See that the 'disassembly' matches the 'native' Flash from which it was copied.  Yes, you will have to debug in said disassembly, as this 'copy process' breaks all the code-reference assumptions of the debug tool.

Particular hints:

Put the function-to-copy at the END of the code module it is in, to maximize your chance of catching any constants following the code.

At least for starters, make ramSpace 'static' and check your linker map to see that ramFunction() does indeed point to it.  Stack-space allocated at the 'outer level' of MAIN is effectively static anyway (allocated directly, and always there).

Since your disassembled-ram-code looks NOTHING like a 'while (1)' loop, I can only assume the memcpy did NOT get the result you desire.

0 Kudos

1,473 Views
johndemayor
Contributor I

Hello,

I'm still stuck on this issue; can someone please help? Someone from NXP?

If you need more information to help solve it please let me know.

Thanks in advance,

John

0 Kudos

1,473 Views
bobpaddock
Senior Contributor III

Doing this without changing the linker script requires writing Position Independent Code (PIC),.

The ARM is capable of doing PIC.  Not the easiest thing to write and requires changes to the build system.


The exact details depend on your part and the tools.

0 Kudos