I need to create some project for MCU on c language, which does not have main() function. This project should be compiled and linked. Functions from this projects can be called by pointer, which should have fixed address. I'm using Eclipse-based IDE for this and GCC toolchain.
For example:
/* linker script SECTIONS: '.fun1 0x601f1000 : {KEEP(*(.fun1))}' */
int (* fun_ptr)(int) __attribute__((section(".fun1"))) = &fun;
int fun(int a)
{
return a*2;
}
int res
void main (void)
{
int (* fun_call_ptr)(int) = (int (*)(int))(*(int*)0x601f1000);
res = (*fun_call_ptr)(10);
}
The goal is to have function 'fun' in one project and 'main' in another. Then build both projects and load both binary files to flash separately.
I guess it can be done by some linker script or makefile, but have no idea how to do it.
I have not specifically done what you describe, but have done similar things, and the approach I would try would be:
-nostartfiles
so that no start-up code is linked (which is what causes main()
to be called.--entry=
option so it does not need a main()
. Alternatively just provide a dummy main()
since with -nostartfiles
nothing will call it. The actual entry
can be any function or a dummy function. Since there is no start-up code, nothing is going to start it. It is just to satisfy the linker.--undefined=
linker option.static
) to prevent the compiler from discarding unused functions.You should then get a fully linked binary that is a collection of functions that need not be explicitly internally referenced.
You could then use the emitted symbol map or nm
output to determine the function entry point. However that requires that your image with the main()
entry point must be built after the nostartup image, and re-built every time the nostartup image changes, obviating any advantage of having a separate image. Instead I suggest that you create a single array of function pointers to each entry point, in a fixed order and locate that table at a specific location (i.e. a vector table). Then you use that to lookup function entry points by index into the table. That way you may also not need multiple undefined
linker options for each separate function, but a single one for the table, and either image can be updated independently, so long as the indexes do not change.
There may be other considerations, but that is the general approach to take I think.