SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: What is the difference between startup code and reset handler?
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

What is the difference between startup code and reset handler?

Ryan Ryan
Last updated: September 13, 2023 3:54 am
Ryan Ryan 12 Min Read
Share
SHARE

When an ARM-based microcontroller powers on or resets, the processor begins executing instructions from a specific memory address. The code located at this address is known as the startup code or boot code. The primary job of the startup code is to initialize the processor, memory, and any peripherals so that the main application code can run properly.

Contents
Startup Code DetailsReset Handler DetailsCode Execution SequenceStartup Code ConfigurationReset Handler ImplementationExample: STM32 Startup vs Reset HandlerStartup Code vs Reset Handler ComparisonTypical Reset SourcesGuidelines for Reset Handler CodeSummary

After the startup code completes its initialization tasks, it must transfer control to the main application code. This is typically accomplished by calling the reset handler. The reset handler is a function or code label defined by the application developer which represents the entry point of the main application code.

In summary:

  • The startup code runs first after reset and sets up the hardware environment.
  • The reset handler is called by the startup code to start executing the main application.

Startup Code Details

When an ARM processor comes out of reset, it loads the value 0x00000000 into the program counter register. This causes execution to begin at the memory address 0x00000000, which is where the startup code is located.

The key tasks performed by the typical startup code include:

  • Initializing processor registers – The startup code sets up important registers like the stack pointer, frame pointer, and control registers.
  • Configuring clock speeds – The system clock and bus clocks are initialized to required speeds.
  • Setting up memory – This includes the flash and RAM memory controllers to allow proper access.
  • Initializing device peripherals – Any required device drivers and peripherals like GPIO, timers, I2C, etc are initialized.
  • Zeroing out RAM contents – RAM contents are cleared or initialized to known values.
  • Copying data sections – Constants and initialized variables are copied from flash to RAM.
  • Calling runtime initialization – Any C/C++ runtime setup code provided by the compiler is called.

The startup code is tightly coupled to the hardware design. It must contain device drivers and setup code for all the specific peripherals used in the microcontroller system. The exact sequence of initialization and configuration tasks may vary across different ARM chips and boards.

Reset Handler Details

After the startup code has performed all its necessary hardware and runtime environment setup, it must transfer control to the main application code. This is accomplished by calling the reset handler function.

The reset handler is a regular C/C++ function defined by the application developer. It has the following key characteristics:

  • Defined with __attribute__((noreturn)) to prevent compiler optimizations.
  • Labelled with __Vectors to locate it in the vector table.
  • Represented by the Reset_Handler symbol in the vector table.
  • Called by the startup code by name or by vector table offset.

A simple reset handler definition in C code looks like: void __attribute__((noreturn)) __Vectors Reset_Handler() { // Application code entry point while(1); // main loop }

When the reset handler function is called, it represents the starting point for the main application program. All application specific initialization, the main loop, and application tasks are written inside the reset handler and called functions.

The reset handler is customized by the application developer and provides the transitions from the generic startup code to the application code. It is responsible for:

  • Calling C++ constructors for global objects
  • Initializing the application’s stack pointer
  • Setting up any custom handlers or interrupt service routines
  • Calling the main() function in C programs
  • Starting the main supervision loop or main task handler

In summary, the reset handler represents the beginning of the application code after the processor and hardware environment has been set up by the fixed startup code.

Code Execution Sequence

To understand the difference between the startup code and reset handler, it is useful to visualize the full code execution sequence on reset:

  1. Microcontroller comes out of reset state
  2. Startup code executes
    • Sets up stack pointer, registers, clocks
    • Initializes memory and peripherals
    • Calls C++ constructors and C runtime init
  3. Reset handler called by startup code
    • Optional application specific initialization
    • Sets up interrupt handlers and application tasks
    • Calls main() function in C program
    • Starts main supervision loop
  4. Main application executes

This clearly shows the separation between the generic startup code provided by the SDK/HAL vendor and the application specific reset handler and main code.

Startup Code Configuration

The startup code is closely coupled to the ARM processor variant and the board or SoC design. Therefore, it must be provided by the silicon vendor as part of a Hardware Abstraction Layer (HAL) or Software Development Kit (SDK).

For example, ARM Cortex-M processors utilize a HAL or CMSIS that contains the startup code and vector table templates. Similarly, microcontroller vendors like STM32, NXP LPC, Microchip SAMD provide startup code and linker scripts tailored for their SoCs.

The application developer must configure the startup code and linker scripts to match their hardware configuration. Key configuration settings include:

  • Processor core variant (Cortex-M3, M4, etc)
  • Clock speeds and oscillators used
  • Memory size and mapping
  • Enabled peripherals and I/O pins used
  • Interrupt priority levels

These settings ensure that the startup code initializes the SoC in the proper hardware state required by the application. SDKs provide configuration tools or #define macros to easily configure the startup code.

Reset Handler Implementation

In contrast to the startup code, the reset handler is fully implemented by the application developer. The compiler combines it with the configured startup code to produce a complete program image.

For simple programs, the reset handler can directly contain the entire application code. For more complex projects, it is structured to call other modules and functions: void Reset_Handler() { // Optional application initialization ConfigurePorts(); ConfigureTimers(); // Start main application tasks InitializeTasks(); StartScheduler(); }

This allows the application code to be cleanly separated from the fixed startup sequence. The use of high-level frameworks can further abstract the reset handler into a configuration based initialization call.

Example: STM32 Startup vs Reset Handler

As a practical example, we can look at an STM32 ARM Cortex-M microcontroller:

  • The STM32F103xx startup code is provided by ST in system_stm32f1xx.c
  • It configures clocks, memory, peripherals based on configuration header files
  • At end, it calls SystemInit() then jumps to reset handler

int main(void) { /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART_UART_Init(); /* Infinite loop */ while (1) { // Application code here } }

  • The developer implements main.c with application specific code
  • Main calls HAL/SDK functions to initialize hardware
  • Main contains infinite loop with application tasks

This demonstrates how the STM32 startup code acts as the fixed bootstrap sequence, while the user main.c behaves as a portable reset handler + application.

Startup Code vs Reset Handler Comparison

Here is a summary comparing the startup code and reset handler:

Startup CodeReset Handler
Executes first after processor resetCalled by startup code to begin main program
Sets up memory and clocksStarts application tasks and functions
Initializes fixed hardware peripheralsOptionally initializes application variables
Provided by vendor SDK/HALImplemented by application developer
Fixed functionality for each MCUPortable code across devices
Boots up the system hardwareEntry point of firmware application

In summary, the startup code acts as a hardware-specific bootloader to configure the system, while the reset handler provides a bridge to portable application code across different microcontrollers.

Typical Reset Sources

The reset handler is versatile to support multiple reset sources and entry conditions in an embedded application. Some common reset causes include:

  • Power-on reset – When power is first applied to the microcontroller.
  • Brownout reset – If the power supply voltage dips below a threshold.
  • Watchdog reset – From a watchdog timer peripheral timeout event.
  • Software reset – Resets intentionally triggered by software.
  • External reset – Using a reset pin to reset from an external circuit or supervisor.
  • Debug reset – When the processor is reset via the debug port.

To handle these different scenarios, the reset handler code can check processor flags or reset status registers to identify the reset source. Special handling for problematic reset sources like brownout or watchdog events can be implemented.

The application may also define a dedicated interrupt service routine (ISR) for the low power reset vector. This allows the main reset handler to remain portable across reset conditions.

Guidelines for Reset Handler Code

Here are some guidelines for effectively implementing the reset handler function:

  • Keep it short and focused on initializing the application only.
  • Avoid complex code since debugging capability may be limited.
  • Initialize the stack pointer first before any stack variables are used.
  • Use static variables with initialization instead of global variables.
  • Check for and handle problematic reset sources like brownout.
  • Jump to main() or the main loop function quickly.
  • Minimize application initialization tasks and instead move them to main().

By following these practices, the reset handler can serve as a lean bridge from the startup sequence into the portable application code in a variety of reset scenarios.

Summary

The startup code and reset handler play complementary roles in an embedded ARM application:

  • The fixed startup code acts as a hardware-specific system bootloader.
  • The flexible reset handler starts execution of the portable application.

Keeping these two stages separate allows reusing application code across different microcontroller systems easily. The reset handler implements a hardware abstraction layer for transition into the common application.

Understanding the distinction between the startup and reset handler code leads to robust firmware design across various ARM platforms.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article What is ARM reset handler?
Next Article What is the final step in the Cortex-M4 processor reset sequence?
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

ARM Processor Architecture

ARM processors are based on the ARM architecture developed by…

7 Min Read

What is ARM Cortex-R4?

The ARM Cortex-R4 is a 32-bit RISC processor core designed…

8 Min Read

Sleep-on-Exit for Automated Low Power in Cortex-M3 (Explained)

Sleep-on-exit is a feature in Cortex-M3 processors that allows the…

23 Min Read

What is the ARM SWD protocol?

The ARM Serial Wire Debug (SWD) protocol is a two-pin…

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

Sign in to your account