I have heard of __attribute__((naked)) in gcc, which is common way place some code into sections, where you don't want to place additional call.
For example in AVR you can frequently find such code stub:
static void __preinit(void) __attribute__((used, naked, section(".init3")));
void __preinit(void) {
wdt_disable();
RESET_Flags = MCUSR;
MCUSR = 0;
}
This code will be placed in section .init3, which is the part of chip initialization, even before RAM initialization (.bss and .data). This is required to pass ram initialization, because otherwise watchdog will fire-up in RAM initialization routine and create a boot-loop.
Based on this i have an idea. In my programs i have a lot of modules, which always have 3 functions: *_init, *_main and *_tick. In this case main.c becomes a mess:
int main() {
init();
while(1) {
loop();
}
}
void init() {
mod1_init();
mod2_init();
...
modN_init();
}
void loop() {
mod1_main();
mod2_main();
...
modN_main();
}
// Same goes for systick handler
If you forget to call some module, debug becomes a useless waste of time. I would like to create a platform for my projects, where you just drop-in c-files for modules and they are called automatically. Just like the way you are not requred to allocate RAM manually, compared to assembly.
What if i define all in-module functions to be placed in corresponding sections:
static void modX_init() __attribute__((used, naked, section(".mod_init")));
static void modX_main() __attribute__((used, naked, section(".mod_main")));
static void modX_tick() __attribute__((used, naked, section(".mod_tick")));
I would be able to merge those functions into some kind of sections, which can be jouned using linker:
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.init_epilogue)
*(.init_epilogue*)
*(.mod_init)
*(.mod_init*)
*(.init_prologue)
*(.init_prologue*)
...
} >ROM
But how do i enter those sections? Should i write myself prologue and epilogue? And how do i know which registers should i push onto stack?
Currently i use ARM microcontrollers, so AVR here is just for an example.
Is there and more-automated way of doing what i had planned?
You iterate over addresses of variables named
__start_<section>and__stop_<section>. Likeextern <type> __start_mod_init;andextern <type> __stop_mod_init. And then all data are between&__start_mod_initand&__stop_mod_init.The problem with storing functions in a section, you do not know the size of the function, unless they are like all the same.
Just store pointers in sections.
Sections starting with
.are technically reserved for linker. Everyone uses them anyway.Consider just: