How to call global constructors
Global objects of C++ classes need to be constructed by the runtime initialization. With the SEGGER Linker this can be done automatically.
In case a constructor makes use of system operations, such as it uses RTOS functions, initialization needs to be deferred until the system is setup.
Automatic Initialization
With a global class object, such as the following, the constructor for the instance is linked into the section .ctors or into init_array.
class foo {
public:
foo(void) {
printf("Foo initialized.\n");
}
};
static foo MyFoo;
The linker script defines a block for all constructors and automatically does the initialization when there is at least one constructor to call.
define block ctors { section .ctors, section .ctors.*, block with alphabetical order { init_array } };
define block dtors { section .dtors, section .dtors.*, block with reverse alphabetical order { fini_array } };
initialize by calling __SEGGER_init_ctors { block ctors }; // Call constructors for global objects which need to be constructed before reaching main (if any). Make sure this is done after setting up heap.
Manual Initialization
It is usually a problem when a constructor uses RTOS functions and is called before main(). In that case the initialization should be done after the basic system is set up.
Remove initialize by calling __SEGGER_init_ctors from the linker script and add the following function:
extern void (*__ctors_start__[])(void);
extern void (*__ctors_end__[])(void);
void init_ctors(void);
void init_ctors(void) {
void (**f)(void);
for (f = __ctors_start__; f < __ctors_end__; f++) {
(*f)();
}
}
Call init_ctors in the application:
int main(void) {
OS_Init() // Initialize RTOS
init_ctors(); // Late initialization of constructors
OS_Start(); // Start RTOS
}