3

We are in the process of modularizing our code for an embedded device, trying to get from $%#!$ spaghetti code to something we can actually maintain. There are several versions of this device, which mostly differ in the amount of peripherals they have, some have an sd card, some have ethernet and so and on. Those peripherals need intialization code.
What I'm looking for is a way to execute the specific initialization code of each component just by putting the .h/.c files into the project (or not). In C++ right now I would be tempted to put a global object into each component that registers the neccessary functions/methods during its initialization. Is there something similiar for plain C code, preferably some pre-processor/compile-time magic?
It should look something like this

main.c

int main(void) {
  initAllComponents();
}

sdio.c

MAGIC_REGISTER_COMPONENT(sdio_init)
STATUS_T sdio_init() {
   ...
}

ethernet.c

MAGIC_REGISTER_COMPONENT(ethernet_init)
STATUS_T ethernet_init() {
   ...
}

and just by putting the sdio.c/ethernet.c (and/or .h) into the project initAllComponents() would call the respective *_init() functions.

TIA

chendral
  • 694
  • 1
  • 6
  • 17

1 Answers1

1

There is nothing in plain C that does this. There are however compiler extensions and linker magic that you can do.

GCC (and some others that try to be compatible) has __attribute__((constructor)) that you can use on functions. This requires support from the runtime (libc or ld.so or equivalent).

For the linker magic (that I personally prefer since it gives you more control on when things actually happen) look at this question and my answer. I have a functional implementation of it on github. This also requires gcc and a linker that creates the right symbols for us, but doesn't require any support from the runtime.

Community
  • 1
  • 1
Art
  • 19,807
  • 1
  • 34
  • 60