Reset Sequence in ARM Cortex-M4

As you are an embedded engineer, have you think anytime, what happens when you press the reset button (Reset Sequence in ARM Cortex-M4)? How it is calling the main() function in your application automatically? And also, If you are attending any interviews, the interviewer might have asked you this question. Okay, Let’s discuss the reset sequence in the microcontroller.

Reset Sequence in ARM Cortex-M4

Before starting this we must know about the microcontroller memory architecture. Please find the below image to know about the Memory map of ARM Cortex-M4.

Here, we have a code region, where we are going to write our final binary. That memory is starting from 0x00000000 to 0x1FFFFFFF. Now we will forget about other regions. We will take only the SRAM and Code region. We know that the code region has the final output of our program (.hex or .bin or etc). SRAM will be having stack, heap, global RW variables, and Static variable etc.

Memory layout of the program

Now we have to know how the final output of our program is stored in the code region. The below image will explain how our program is stored in the code region. As you can see from the above image, the final output of our program will be ordered in this way by using a linker. If you want to know the memory layout of the program, you can refer to this tutorial. So, the vector table is starting from 0x00000000.

Note: By default vector table will be starting from 0x00000000.

Vector table of ARM Cortex_M4

That vector table will contain all the locations of the exception and interrupt ISR. As Cortex-M4 has below exceptions, interrupts and those things are ordered in the below image.

vector tableSo, 0x00000000 address contains initial Stack Pointer Value. Then 0x00000004 has the address of the reset handler. Once you press the reset button or powerup the controller, below things will happen.

What happens When you press the reset button in ARM Cortex-M4?

  1. PC (Program Counter) will be loaded with 0x00000000. So will start from the address 0x00000000.
  2. Since the address has Initial Stack Pointer value, It will be fetched to the MSP (Main Stack Pointer). So that value will be starting of the stack.
  3. Then PC will be loaded with Reset handler’s address.

Note: These above 3 steps are done by the hardware (This is architecture-specific).

4. After that, the reset handler will perform below operations.

      1. Initialize the system.
      2. Copy the Initialized global variable, static variable (.data) to SRAM.
      3. Copy the Un-initialized data (.bss) to SRAM and initialize it to 0.
      4. It Calls main().

This is how your main() is getting called while power-up or press the reset button. You may understand clearly if you see the execution below.

Example execution

I am using IAR IDE and STM32. Each controller has a specific startup file that has all the ISR’s address (vector table). In my case, I have startup_stm32l4xx.s file. I am going to run through a debugger (J-Link). Using that we will step by step.

I have attached some lines of the startup file.

        DCD     sfe(CSTACK)
        DCD     Reset_Handler             ; Reset Handler

        DCD     NMI_Handler               ; NMI Handler
        DCD     HardFault_Handler         ; Hard Fault Handler
        DCD     MemManage_Handler         ; MPU Fault Handler
        DCD     BusFault_Handler          ; Bus Fault Handler
        DCD     UsageFault_Handler        ; Usage Fault Handler
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     SVC_Handler               ; SVCall Handler
        DCD     DebugMon_Handler          ; Debug Monitor Handler
        DCD     0                         ; Reserved
        DCD     PendSV_Handler            ; PendSV Handler
        DCD     SysTick_Handler           ; SysTick Handler

The above code is not a full code. I just provided some lines for your understanding. If you see the above code, the vector table’s first place contains Stack. This is the initial SP. Then after that, they have passed the Reset_Handler‘s address.

Now I am going to start debugging.

  • Refer the below image, the cursor points to Reset_Handler and SP also points to 0x20000800. And other registers are initialized to zero. Now loading the SystemInit into R0 register.

  • Then using the BLX command, it is branching to SystemInit function. There it will initialize the system.
  • Once it’s done with the system initialize, it will load the __iar_program_start to R0 register. Check out the below Image.

  • Since we are using IAR it using __iar_program_start function. This is IAR specific function.
  • You can not find the source of the __iar_program_start. But you can see those kinds of stuff in the Disassembly window of IAR.
  • There you can see that it is going into __iar_init_vfp, which initializes the hardware floating-point unit (FPU). Check out the below Image.

  • Then there is it will jump to ?main function. Check out the below Image.

  • In ?main, it calls, __low_level_init. This function is intended to perform a customized initialization of your hardware that either must occur very early on or can speed up the startup process. For example, if you plan to increase the CPU clock speed, it’s better to do it sooner so that the rest of the startup code will execute faster. Check out the below Image.

  • As you can see by the test of the R0 register, __low_level_init returns a value that determines whether to go straight to calling main or to perform a data initialization. It returns a non-zero value, so the function __iar_data_init3 is called. Check out the below Image.

  • __iar_data_init3 will copy the data to SRAM (.data). And also copy the .bss data to SRAM and initialize it to 0 with the help of __iar_zero_init3.  Check out the below Image.

  • After that, finally, it calls _call_main function. In that _call_main function, we are calling the original main() function. Check out the below Image.

That’s all.


  • When you press the reset button, it will copy the Stack pointer to MSP (Main Stack Pointer) from the location of 0x00000000.
  • Then it moves to Reset_Handler.
  • In the Reset_handler, it will initialize the hardware (system), then copy the initialized data (Initialized global variable and static variable) to SRAM.
  • Then copy the uninitialized data to SRAM and initialize with 0.
  • Finally, it calls our main function.

Note: This process is applicable when you don’t have a bootloader. If you have a bootloader, then it will execute in a different way.

What happens when you have a bootloader?

  • When you press the reset button, it will copy the Stack pointer to MSP (Main Stack Pointer) from the location of 0x00000000.
  • Then it moves to your bootloader. (Because you would have given bootloader’s function as an entry point).
  • The bootloader will do some operations based on your need like check for firmware version, upgrade the firmware, etc.
  • Then it will initialize the MSP (Main Stack Pointer).
  • Since you have the bootloader at the starting point, you might have placed your vector table at some other place of RAM or ROM. So, the bootloader has to load the vector table address using a Vector Table Offset Register (VTOR).
  • Then it will jump to your application.

Now you know how our main function is getting called? Good. Happy programming :-P.

5 2 votes
Article Rating
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x