In this tutorial, we will discuss about the booting sequence of a microcontroller. We will see what happens when a microcontroller resets and how microcontroller control transfers to the main function of appliation.
Bare-Metal Embedded systems
In bare-metal embedded systems, usually, microcontrollers are used. In these types of embedded systems, there is no operating system, or Kernel is used to manage microcontroller resources. A bare-metal code directly runs on the microcontroller. A super while loop executes the same piece of code again and again. But have you ever wondered, what happens when microcontroller resets or what is the booting process of a microcontroller? In other words, how microcontroller determines that it has to start execution of a program from a main() function of the code?
How Microcontroller reach to the main function?
The answer to this question is that every microcontroller has a well-defined booting process or reset sequence. Embedded software developers usually don’t care about the booting process of a microcontroller. Because every microcontroller vendor or IDE provides a startup file for every microcontroller. The startup file is basically a code written in C language or assembly language and it performs various functions such as booting sequence, initialization of RAM, and transfer control to the main function. It also contains the interrupt vector table and interrupts service routines for each interrupt or exception.
When you compile a specific microcontroller code in IDE such as Keil, the compiler will automatically add this startup file into your code binary image and when you upload this binary image to a microcontroller, this startup file will be available in microcontroller flash memory along with actual application program.
Microcontroller Booting sequence
In order to understand the reset sequence of a microcontroller lets take an example of TM4C123G series microcontrollers. But the booting process and concept remain the same for other microcontrollers also.
Microcontroller booting sequence starts as soon as we apply power to the microcontroller or press the reset button. After that microcontroller fetches the first instruction from address zero where the address of reset handler will be available.
TM4C123G Microcontroller Interrupt Vector Table Memory Map
But the question is how a microcontroller knows the address of first instruction? In order to explain this, let take a look at the addressable memory space of TM4C123G microcontrollers. TM4C123G is a 32-t bit microcontroller and an addressable memory space starts from 0x0000_0000 and ends on 0xFFFF_FFFF. The starting addresses that are from 0x0000_0000 contains the interrupt vector table. As shown in the figure below:
What Happens When Microcontroller Resets?
- When microcontroller resets, program counter or PC is loaded with the address 0x00000000, this first address contains the address of the top of the stack or the value that will be loaded to the main stack pointer.
- After that microcontroller loads the value stored at the address 0x00000000 to the main stack pointer or MSP.
- Now PC moves to the next address by increment its value by 4. Because the program counter always moves to the next address. The next address is 0x00000004 and the value at address 0x00000004 contains a pointer to a reset handler function.
Note: The program counter of microprocessor or microcontroller holds the address of the next instruction to be executed.
The program counter of a microcontroller is loaded with the address of the reset vector. Now microcontroller starts executing instructions of reset vector. These instructions are not the typical main code of your application. Instead, these reset handler instructions perform various initialization steps before calling the main function.
Reset handler function
Reset vector or reset handler function performs hardware initialization such as :
1. Disable all interrupts
Firstly, it disables all interrupts so that microcontroller cannot be able to execute any other interrupt service routine such as watchdog time, etc
When you upload your code to a microcontroller, the binary image of code gets stored in flash memory. Because flash is a non-volatile memory. Therefore, code stores there permanently even without power. During the microcontroller booting process, some data which is stored in flash memory is moved to the RAM.
But the question that might come to your mind is that what is the reseason for copying data from flash to RAM of microcontroller? This is because RAM works faster than flash memory and hence it helps to reduce the latency of data accesses from memory.
2. Initialize data segment
If you remember the layout of a running C program then you must remember that the initialized global, static global and static local variables store in the .data section of memory. Reset handler assign memory region to .data section and moves the content of the initialized data section from flash to RAM memory region of the microcontroller.
3. Initialize the .Bss segment
In our embedded program, we use both initialized and uninitialized static and global variables. The uninitialized static, global static, and local static variables store in the .bss segment of memory. The .bss section also copies from flash to RAM and zero all uninitialized variables.
4. Initialize stack segment
The stack segment is a sub-segment of RAM memory. Reset handler reserves the stack space in data memory according to pre-compiled instructions given in the linker file. The stack memory region is used to hold temporary variables, input arguments, and return addresses of functions.
The last two steps are straight forward.
5. Enable interrupts
6. Call the main function
Note: You can also move interrupt vector tables from flash to ROM. Because it will reduce the interrupt latency and interrupt service routines will execute faster. But for this, we will have to change the linker script file. It also depends if the microcontroller has sufficient RAM available. Because microcontroller usually comes with higher flash memory than RAM. Flash memory is used to store code and RAM is also known as data memory.
Finally, after completing all these initialization steps, the microcontroller transfers the control to the main function of your application. This is how microcontroller boots up and the reset sequence is pretty easy. To go into in-depth details of this process, we recommend you try to analyze the startup file of a microcontroller.