SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: ARM Cortex M Boot Sequence
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

ARM Cortex M Boot Sequence

Graham Kruk
Last updated: September 8, 2023 12:46 pm
Graham Kruk 6 Min Read
Share
SHARE

The ARM Cortex-M processor family is designed for embedded applications requiring high performance and low power consumption. Cortex-M processors are based on the ARMv7-M architecture and include features like Thumb-2 instruction set, NVIC for interrupt handling, and SysTick timer for OS task scheduling. When power is first applied to a Cortex-M based microcontroller, it goes through a well-defined boot sequence to initialize the core registers and peripherals.

Contents
Reset SequenceReset HandlerSystem Initialization.data and .bss InitializationC Runtime InitializationCalling main()Startup OptimizationSummary

Reset Sequence

After power on reset or external reset signal, the Cortex-M processor loads the main stack pointer (MSP) with the value from address 0x00000000. This is where the processor expects the initial stack pointer value to be located. The reset value of MSP is configurable and provided by the microcontroller manufacturer. ARM recommends setting MSP to point to the start of the RAM region. After MSP initialization, the processor loads the reset value into the vector table offset register. This specifies the location of the vector table which holds the reset handler address and interrupt handler addresses. The standard location for the vector table is address 0x00000000. The processor then fetches the reset handler address from the first word in the vector table (0x00000000) and jumps to the reset handler code.

Reset Handler

The reset handler is responsible for initializations that must be done before calling main(). This includes:

  • Setup core peripherals like SysTick timer and NVIC
  • Initialize device specific peripherals
  • Copy .data section initial values from flash to RAM
  • Clear the .bss section in RAM
  • Initialize the heap and stack
  • Call library initializers for C runtime and middleware
  • Call the main() function

The reset handler code can be written in assembly or C. Assembly allows precise control over the initialization sequence but C is more portable. A typical C implementation would look like: void Reset_Handler() { // Initialize core peripherals SystemInit(); // Initialize device peripherals // E.g. GPIO, UART, I2C, etc // Initialize .data and .bss sections __init_data(); // Call C library initializers __libc_init_array(); // Call main main(); }

System Initialization

The SystemInit() function is used to setup core peripherals like the SysTick timer and NVIC. This typically involves:

  • Configure SysTick for OS task scheduling
  • Set NVIC priorities for interrupts
  • Enable desired interrupts in the NVIC
  • Configure optional MPU regions for memory protection
  • Enable FPU if present

The configuration values are vendor specific and configured through CMSIS headers provided by the manufacturer. This abstracts the core initialization from the underlying MCU hardware.

.data and .bss Initialization

The .data section contains initialized global and static variables that need to be copied from flash to RAM on startup. The __init_data() function loops through the .data section and copies values from the flash to the RAM address for each variable. After copying, the .data variables will contain their initialized values.

The .bss section contains uninitialized global and static variables which need to be zero initialized in RAM. The __init_data() function will clear the .bss section, typically by just memsetting it to zero before the main() call.

C Runtime Initialization

The C runtime contains startup code that must be executed before entering main(). This includes:

  • Initialize heap region for dynamic memory allocation
  • Initialize global C++ objects
  • Initialize stdin, stdout, stderr
  • Initialize C library state

The __libc_init_array() function will invoke the C runtime startup routines. The ARM compiler tools provide the implementation for this based on the compiler settings.

Calling main()

After C runtime initialization, the reset handler calls the main() function to start application execution. The arguments argc and argv are setup according to the application. With no OS, main() will never return and the program executes forever in the application code.

With an RTOS, main() will initialize the OS kernel and start the scheduler. It will then return after creating the OS tasks. The scheduler will take over execution from main() by running the created tasks in a multithreaded environment.

Startup Optimization

To optimize the startup time, various techniques can be used:

  • Initialize only required peripherals in the reset handler
  • Configure flash wait states to match CPU clock speed
  • Optimize .data and .bss copy by using DMA
  • Execute startup code from RAM instead of flash

Toolchain options can also impact startup time. For example, the –split_sections option generates faster code by splitting linker sections into separately loadable segments.

Startup time can be measured from reset release to the entry of main(). By optimizing the reset sequence and peripherals initialization, it can be reduced from milliseconds to hundreds of microseconds.

Summary

The ARM Cortex-M boot sequence follows a well-defined startup procedure to transition the device from reset to application execution. Configuring the MSP stack pointer, vector table offset, and reset handler are the critical first steps. The reset handler then initializes the system, C runtime environment, and application variables before calling main(). Optimization of the startup code improves embedded responsiveness and real-time performance.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article bkpt Instruction in ARM
Next Article How to Write a Bootloader for a Microcontroller
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

Modifying Stack Pointer (SP) and Program Counter (PC) in Cortex-M1

The stack pointer (SP) and program counter (PC) are important…

6 Min Read

Cortex-M0 STM32

The Cortex-M0 is a 32-bit ARM processor core designed for…

7 Min Read

Inline assembly in C code for Cortex-M0/M0+

Inline assembly allows inserting assembly language code directly into C/C++…

7 Min Read

What are SP (stack) and LR in ARM?

The stack pointer (SP) and link register (LR) are important…

8 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account