AnsweredAssumed Answered

Copy and execute code from RAM

Question asked by John Demayor on Jul 10, 2016
Latest reply on Jul 27, 2016 by EARL GOODRICH



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){

int main(void) {
  uint8_t ramSpace[100];
  void (*ramFunction)(void);

  /* Init board hardware. */

  // RAM test
  memcpy(ramSpace, ATO_RomFunc, 100); //Don't care for now if more code is copied than needed
  ramFunction = (void (*)(void))ramSpace;
  ramFunction++; // Add 1 address for thumb


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