When we learn C/C++ then it is told that the code starts from main(). But does the microcontroller start from main() or does it have something to do before main() also?
A C/C++ code compilation process have mainly 4 steps i.e., Preprocessing, Compiling, Assembling, Linking. We will discuss all these steps in some other article, but we need to understand that after executing these steps, an executable is generated. This executable is used to flash into microcontroller/microprocessors.
We also get a linker map file (.map) after the compilation process. We can use “LDFLAGS += -Wl,-Map=output.map” to generate the map file (here output.map is name of file that will be generated). A .map file give a lot of information e.g. the address of all the functions, vector table, text segments variables etc.
Before reaching to main(), the microcontroller needs to arrange all the memory segments & initialization the variables, reset the CPU, load the vector table etc. Once all these arrangements are done then only it moves ahead and start executing the code from main(). Let us discuss these one by one.
Whatever C code that we have written goes to the text segment. We can check the text segment in the map file also. All the uninitialized variables go to .bss segment which is also known as uninitialized segment. All the static variables and initialized variables go to Initialized data segment.
Vector table load:
First of all, the MCU puts the default vector table then it updates the vector table according to the interrupt that was configured in the program. In this way the complete vector tables becomes effective much before main().
After handling all the memory related stuff, MCU reset the CPU. Then it loads the stack pointer to 0x00.
In ARM based microcontroller/microprocessors, startup code is executed before jumping to main() function.