简体   繁体   中英

stm32f4 - copy a function from the flash to the ram on runtime

I'm having an issue with my stm32f4 , I'm trying to copy a function from the flash to the ram (kind of POC for something). I've managed to make it work when the function was very simple (increasing a counter), however when I'm trying to call a flash function from the function i copied to the ram the controller gets a hardfault

Again this is a pure POC... I also cant use __ramfunc as I need to do it on runtime...

The code is something like this:

void dummy_func2() 
{ 
    var2++;
} 

void dummy_func()
{ 
    var++;
    dummy_func2(); 
} 

void copy()
{ 
    memcpy(buffer, (void*)((uint32_t)&dummy_func & ~1), 100);
    run_func = (pFunc) &buffer[1];
}


void main()
{ 
    copy();
    while(1) 
    {   
        run_func(); 
    }
}

thanks! 😊

Your problem is that you can't ... convert a pointer-to-member-function to a void? and can't ... convert a pointer-to-function to a void?

Technical details: void* pointers are pointers to data, and function pointers point to functions. The language does not require functions and data to be in the same address space,...

What you could do is use the linker to place certain functions at certain spots inside your flash memory and write a function to load from that certain memory space. This can be done as shown here and here .

It involves creating a new memory region with your custom name. In the example this is MY_MEMORY

MEMORY
{
    FLASH (rx) : ORIGIN = 0x0, LENGTH = 128K
    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32k
    MY_MEMORY (rx) : ORIGIN = 0x20000, LENGTH = 128k
}

You then declare a section which can be used to place functions (or data) inside of it.

__etext = .;

.mysection :
{
  . = ALIGN(4);
  __mysection_start__ = .;
  *(.mysection*)
  __mysection_end__ = .;
} > MY_MEMORY

You'll need to add a size check for added safety to your linker script so you won't overflow your memory area.

/* Check if FLASH usage exceeds FLASH size */
  ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
  
  /* Check if MY_MEMORY usage exceeds MY_MEMORY size */
  ASSERT( LENGTH(MY_MEMORY) >= (__mysection_end__ - __mysection_start__), "MY_MEMORY memory overflowed !")

And now you can locate a function inside a certain memory section and read the data from it.

#define LOCATE_FUNC  __attribute__((__section__(".mysection")))

void LOCATE_FUNC Delay(uint32_t dlyTicks)
{
  
}

please note that this tutorial was copied from the silabs ChrisM Q/A page and as such isn't my work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM