Skip to main content
Explorer
February 25, 2024
Solved

Help with load & Executing Code into Stm32 mcu Ram

  • February 25, 2024
  • 2 replies
  • 2401 views

I have both STM32F1038T6 and STM32F401CC. I have been trying to get a code to run from ram for days now. 

Im using arduino ide with stm32duino. 

 

i first create a buffer in ram with malloc then  copy the code to the buffer using memcpy. The code is in  byte array inside a  include file.

 

Like for example

memcpy_P(RamAddr, mCode, 2904);
 
void (*functionPtr)(void);
functionPtr = (void(*)(void))RamAddr;
functionPtr();

 

RamAddr is a byte pointer. Also the above code is in a method function that is called in Arduinos' loop()

 

The code is copied properly. When functionPtr() is called the Program counter loads the Address of the function (Which is the start of the code) and I can see it when debugging it. However the pc increments normally but nothing happens and if left to run it ends up in WWDG_IRQHandler as pointer by Program counter. The mCode code  just blinks PC13 on and off and was built from Stm32CubeIde. I tried the blink program by flashing it directly to mcu and it works. 

So am i doing something wrong or missing something? If so how can it be done with examples. Because i want to be able to load code from spi flash or memory card

 

 

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    https://community.st.com/t5/stm32-mcus-products/bootloader-and-jumping-to-flash-location/td-p/462009

    typedef int (*pFunction)(void);
    void RamCode(void)
    {
     static const uint16_t Code[] = { 0xF04F, 0x007B, 0x4770 }; // payload
     uint8_t Buffer[16]; // as big as required
     pFunction RunCode;
     memcpy(Buffer, Code, sizeof(Code)); // Copy code
     RunCode = (pFunction)&Buffer[1]; // +1 for Thumb code
     printf("%d\n",RunCode());
    }
     MOV R0, #123
     BX LR

    2 replies

    Graduate II
    February 25, 2024

    Have a Hard Fault Handler to catch failures.

    The function pointer needs to be an ODD address. Suggest you print if out to confirm.

    ie 0x20002001 for code you copy to 0x20002000

    KeiKeiAuthor
    Explorer
    February 25, 2024

    In the data sheet it says bit 0 is not set in PC and it must be half word aligned. And i tried odd address before it does the same thing. so im using Even addresses.

    Graduate II
    February 25, 2024

    Try something simple than loads R0 with a value and returns.

    You'd need to show the code, and a disassembly to be able to trouble shoot from here.

    It needs to be THUMB code, you need to copy on an even address, and call at the odd address. That's how the Cortex-M3 expects things.

    Create a pointer for a function you can uses successfully, and print out the value. Say for a qsort() implementation, which takes a pointer for a compare function.

    Graduate II
    February 25, 2024

    https://community.st.com/t5/stm32-mcus-products/bootloader-and-jumping-to-flash-location/td-p/462009

    typedef int (*pFunction)(void);
    void RamCode(void)
    {
     static const uint16_t Code[] = { 0xF04F, 0x007B, 0x4770 }; // payload
     uint8_t Buffer[16]; // as big as required
     pFunction RunCode;
     memcpy(Buffer, Code, sizeof(Code)); // Copy code
     RunCode = (pFunction)&Buffer[1]; // +1 for Thumb code
     printf("%d\n",RunCode());
    }
     MOV R0, #123
     BX LR
    KeiKeiAuthor
    Explorer
    February 26, 2024

    I got it to work. I was getting the error because i was  modifying 4 registers, r1,r2,r3,r4 which were used by rtos so what i did was push these registers then run my code. After code runs, i pop the registers then use BX LR.

     also another error i was getting was because of  using wrong push and pop instructions. There is two versions of both push and pop. For push there is 0xB4 and 0xB5 and for pop there is 0xBC and 0xBD. I had to use 0xB4(push) with 0xBC(pop) and if i used 0xB5(push) then use 0xBD for pop. Any other combination causes a fault.

    for the new code it looks like this

     

    byte nCode[14] = { 0x10,0xB5,0xFE,0x21,0xED,0x22,0xBE,0x23,0xBF,0x24,0x10,0xBD,0x70,0x47 };

    Thanks for the help. Really appreciate it.