If you are anything like me, you have landed here because you are wondering about all those files generated by the IDE and how you can edit and use them to your advantage, or perhaps simply to understand what they are and what their purpose is.
No matter your reason for being here it is safe to say that understanding those files and how your microcontroller gets to main will only make you a better engineer/student/hobbyist because not every project lends itself to an IDE.
Imagine a huge project with multiple dependencies and multiple binaries that need to be merged etc….
Messing around with all of that in an IDE is actually more trouble then mainingting a Makefile , not to mention IDE and their “updates” can break things and then you are in a place where you have to keep a certain version of something around just for compatibility.
I will only explain the sequence of events that occurs at boot from a firmware developer’s perspective, meaning I will not go into detail about voltages and power sequencing. We will write the necessary files to build a project completely free of an IDE.
This may not be an exhaustive tutorial on every aspect of linker scripts, Makefiles, startup files but it will be more than enough to get you to main.
Furthermore there are some different things happening in different Cortex cores not to mention different boot modes. For the sake of sanity, clarity and brevity I will discuss the normal boot process of a Cortex M4.
Just because we will not be using an IDE does not mean we do not require some ready made tools like compiler , linker, GDB etc… But I will discuss those requirements in the next part.
ARM Cortex Power Up Sequence
At power up the PC (program counter) is loaded with address 0x00000000. The contents of address 0x00000000 are loaded into the SP (Stack Pointer), or MSP (Main stack pointer) is usually the case. This value is effectively the top address of your RAM type memory region.
But why the top address?
The MSP is located at the top of RAM because the stack is a full descending stack that grows down, so to speak.
From the highly advanced image above only available to industry insiders, we can see that the stack mechanism grows down towards the lower address while the heap memory space grows upward. Both of these mechanisms grow dynamically. Note that your application may or may not require heap allocation. But you always need stack space.
Next the processor jumps to address 0x00000004 and reads that value into the PC. Out of pure coincidence, or perhaps by design, that value happens to be the address of the reset handler so naturally the next instruction to get executed is the reset handler and from there it’s smooth sailing to main.
How do these values get there?
How do you program those values if the MCU needs to be running in order for any of your code to even work? Is this a chicken and egg scenario? Two words my friend: Vector table, here's another two words: linker script and two more: startup file.
Those 3 things are the main components that we need to write by hand in order to get to main. Obviously the devil is in the details and there are other files that we will need but by no stretch of the imagination will we try to write them by hand. Such files include, device header file with all register definitions and as well as some cmsis files relevant to the core registers, provided by ARM. Some of those files are thousands of lines long and are auto generated by the MCU vendor and ARM.
In the next post we will get the necessary components such as compiler and documentation as well as those header files by ARM and the MCU vendor. Do not fret, all of this may sound like it will be complicated but it is not. ARM mcus are relatively easy to get up and going and we dont even need to use any assembly if we do not want to, and we wont. So get in fools were going coding.
(if this is not clickable then you are here too early I have not finished writing the next post yet)