cancel
Showing results for 
Search instead for 
Did you mean: 

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

aykutulusan
Associate II
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?

5 REPLIES 5
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
Up vote any posts that you find helpful, it shows what's working..
qwer.asdf
Senior
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
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();

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
Up vote any posts that you find helpful, it shows what's working..
aykutulusan
Associate II
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.