Skip to main content
aykutulusan
Associate II
August 19, 2016
Question

can I move a C function to sram from program memory?

  • August 19, 2016
  • 5 replies
  • 1363 views
Posted on August 19, 2016 at 15:14

Hello,

for example: there are stand alone function in program memory,

it doesn't include another function(s), it is not nested, I want to move to sram and to run it there.

void MyFunc(void) // in program memory
{
....
}

is it possible? if yes, how can I move and use it? Please can you give me a short sample?

    This topic has been closed for replies.

    5 replies

    Tesla DeLorean
    Guru
    August 19, 2016
    Posted on August 19, 2016 at 15:27

    Yes, although doing math can call helper/library functions.

    IAR has a ''ramfunc'' option. Other tool chains have attributes or pragmas to direct code into specific segments/sections, which can include RAM. One can also memcpy() the function code and literal pool into another location, and then transfer control via a function pointer. Observe how qsort() works. This is a topic I've covered here before. Please review other threads.

    int TestFunc(void)
    {
    return(123);
    }
    #define FUNC_SIZE 64
    typedef int (*pFunction)(void);
    int RamFunc(void)
    {
    uint8_t Buffer[FUNC_SIZE];
    pFunction RunFunc;
    memcpy(Buffer, (void *)((uint32_t)&TestFunc & ~1), FUNC_SIZE); // Copy code
    RunFunc = (pFunction)&Buffer[1]; // +1 for Thumb code
    return(RunFunc()); // sourcer32@gmail.com
    }

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    qwer.asdf
    Senior
    August 19, 2016
    Posted on August 19, 2016 at 15:58

    If you are using a GCC based toolchain just add a small attribute to your function definition and that's all:

    void EXTI9_5_IRQHandler(void);

    becomes

    void EXTI9_5_IRQHandler(void) __attribute__((section (''.data'')));

    where .data is your data section (look in your linker *.ld files).

    aykutulusan
    Associate II
    August 19, 2016
    Posted on August 19, 2016 at 22:30

    Thanks a lot for replies

    Dear clive1, Likewise for nested functions, Can I use as follows? There are 3 functions but they are nested, Can I move them to sram in program memory while cpu is working, and run them ?

    typedef
    void
    (*pFuncP1_t)(u8);
    typedef
    u8 (*pFuncP2_t)(u32, u32);
    typedef
    void
    (*pFuncP3_t)(u8, u32, u32);
    typedef
    struct
    {
    u8 Fonc1_Buf[FONC1_BUF_SIZE];
    u8 Fonc2_Buf[FONC2_BUF_SIZE];
    u8 Fonc3_Buf[FONC3_BUF_SIZE];
    pFuncP1_t pFoncP1;
    pFuncP2_t pFoncP2;
    pFuncP3_t pFoncP3;
    }FoncPtrs_t;
    FoncPtrs_t FoncPtrs;
    void
    Fonc1(u8){
    ...
    }
    void
    Fonc2(u32, u32){
    ...
    Fonc1(u8);
    } 
    void
    Fonc3(u8, u32, u32){
    ...
    Fonc2(u32, u32);
    } 
    // in program
    memcpy
    (FoncPtrs.Fonc1_Buf, (
    void
    *)((uint32_t)&Fonc1 & ~1), FONC1_BUF_SIZE); 
    // func1 copy
    FoncPtrs.pFoncP1 = (pFuncP1_t)&FoncPtrs.Fonc1_Buf[1];
    memcpy
    (FoncPtrs.Fonc2_Buf, (
    void
    *)((uint32_t)&Fonc2 & ~1), FONC2_BUF_SIZE); 
    // func2 copy
    FoncPtrs.pFoncP2 = (pFuncP1_t)&FoncPtrs.Fonc2_Buf[1];
    memcpy
    (FoncPtrs.Fonc3_Buf, (
    void
    *)((uint32_t)&Fonc3 & ~1), FONC3_BUF_SIZE); 
    // func3 copy
    FoncPtrs.pFoncP3 = (pFuncP1_t)&FoncPtrs.Fonc3_Buf[1];
    FoncPtrs.pFoncP3();

    Tesla DeLorean
    Guru
    August 19, 2016
    Posted on August 19, 2016 at 22:39

    As presented that isn't going to work.

    You would be better managing the functions into a RAM section using the Scatter File for the linker.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    aykutulusan
    Associate II
    August 19, 2016
    Posted on August 19, 2016 at 22:57

    Thanks,

    in fact, I'm using the same way now (into sram section using the scatter file for bootloader). I'm trying to know this is possible.