In order to ensure that some initialization code runs before main
(using Arduino/avr-gcc) I have code such as the following:
class Init {
public:
Init() { initialize(); }
};
Init init;
Ideally I'd like to be able to simply write:
initialize();
but this doesn't compile...
Is there a less verbose way to achieve the same effect?
Note: the code is part of an Arduino sketch so the main
function is automatically generated and cannot be modified (for example to call initialize
before any other code).
Update: ideally the initialization would be performed in the setup
function, but in this case there is other code depending on it which occurs before main
.
Use static members of classes. They are initialized before entering to main. The disadvantage is that you can't control the order of the initialization of the static class members.
Here is your example transformed:
Here's a somewhat evil method of achieving this:
Add the following to the linker flags:
--wrap main
eg.
The linker will replace all calls to
main
with calls to__wrap_main
, see the ld man page on--wrap
You can use GCC's
constructor
attribute to ensure that it gets called beforemain()
:There is how I perform pre-main coding. There are sever init sections executed before main, refers to http://www.nongnu.org/avr-libc/user-manual/mem_sections.html initN sections.
Anyhow, this only works on -O0 optimization for some reason. I still try to find out which option "optimized" my pre-main assembly code away.
Update, it turns out I claimed this function is unused, leading to optimize the routine away. I was intended to kill function unused warning. It is fixed to used used attribute instead.
You can use the ".init*" sections to add C code to be run before main() (and even the C runtime). These sections are linked into the executable at the end and called up at specific time during program initialization. You can get the list here:
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
.init1 for example is weakly bound to __init(), so if you define __init(), it will be linked and called first thing. However, the stack hasn't been setup, so you have to be careful in what you do (only use register8_t variable, not call any functions).
Your solution in simple and clean. What you can additionally do is to put your code in anonymous namespace. I don't see any need to make it better than that :)