Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I perform pre-main initialization in C/C++ with avr-gcc?

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.

like image 507
Matthew Murdoch Avatar asked Jun 04 '09 11:06

Matthew Murdoch


2 Answers

You can use GCC's constructor attribute to ensure that it gets called before main():

void Init(void) __attribute__((constructor));
void Init(void) { /* code */ }  // This will always run before main()
like image 98
Adam Rosenfield Avatar answered Nov 01 '22 18:11

Adam Rosenfield


You can make the above very slightly shorter by giving "initialize" a return type, and using that to initialize a global variable:

int initialize();
int dummy = initialize();

However, you need to be careful with this, the standard does not guarantee that the above initialization (or the one for your init object) takes place before main is run (3.6.2/3):

It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the first statement of main.

The only thing that is guaranteed is that the initialization will take place before 'dummy' is ever used.

A more intrusive option (if it's possible) might be to use "-D main=avr_main" in your makefile. You could then add your own main as follows:

// Add a declaration for the main declared by the avr compiler.
int avr_main (int argc, const char * argv[]);  // Needs to match exactly

#undef main
int main (int argc, const char * argv[])
{
  initialize ();
  return avr_main (argc, argv);
}

At least here you're guaranteed that the initialization will take place when you expect.

like image 32
Richard Corden Avatar answered Nov 01 '22 17:11

Richard Corden