SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: What is the startup code of ARM in C?
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 startup code of ARM in C?

Holly Lindsey
Last updated: September 13, 2023 5:27 am
Holly Lindsey 8 Min Read
Share
SHARE

The startup code of an ARM processor written in C is responsible for configuring the processor and setting up the environment before the main() function is called. This involves tasks like initializing registers, enabling interrupts, copying data sections to RAM, and jumping to the main() function. The exact startup code varies depending on the specific ARM processor being used, the toolchain, and the application requirements. However, the general structure and key tasks are similar across most ARM C startup codes.

Contents
Purpose of the Startup CodeTypical Sections of an ARM C Startup Code1. Reset Handler2. Processor Initialization3. .data Initialization4. .bss Initialization5. Interrupt Vector Table Setup6. Enable Interrupts7. Call Static Constructors8. Jump to main()A Simple ARM C Startup Code ExampleKey Startup Code Implementation DetailsToolchain Specific Startup CodeGCC Startup CodeARM Compiler Startup CodeIAR Startup CodeTips for ARM C Startup CodeConclusion

Purpose of the Startup Code

The main purposes of the ARM C startup code are:

  • Initialize hardware peripherals like clocks, memory controllers, GPIO pins, etc.
  • Configure stack pointers and heap memory
  • Copy initialized data from flash to RAM
  • Clear uninitialized data sections (BSS)
  • Configure interrupt vectors
  • Enable interrupts
  • Call static constructors
  • Jump to main() function

Handling these essential setup tasks allows the startup code to prepare the environment for the application code. Without proper configuration by the startup code, the processor and memory would be in an unknown state, interrupts would not function, and calling the main() function could result in a crash.

Typical Sections of an ARM C Startup Code

A typical ARM C startup code contains the following high-level sections:

1. Reset Handler

This label indicates the entry point that the processor will start executing from after a reset. It must be placed at the very start of the startup code.

2. Processor Initialization

This section sets up core registers like the stack pointer, initializes clocks, and configures memory controllers.Low-level processor initialization takes place here.

3. .data Initialization

The .data section contains global and static variables that have been initialized. This startup code routine copies the .data section from flash to RAM.

4. .bss Initialization

The .bss section contains global and static variables that have not been initialized and just reserve space. This startup code routine clears the .bss section to zero.

5. Interrupt Vector Table Setup

The interrupt vector table contains the handlers for exceptions and peripheral interrupts. This section sets the location of the vector table and populates it with handler functions.

6. Enable Interrupts

Interrupts are globally disabled on reset. This startup code section enables interrupts so that exception and peripheral interrupts can occur.

7. Call Static Constructors

Any global C++ objects with constructors need to have their constructors called at startup before main(). This section calls all the registered static constructors.

8. Jump to main()

After all initialization is complete, the startup code jumps to the main() function to begin application execution.

A Simple ARM C Startup Code Example

Here is a basic example ARM C startup code for an ARM Cortex-M4 processor using GCC: /* Reset Handler */ void Reset_Handler(void) { /* Initialize core registers */ SystemInit(); /* Copy .data sections from flash to RAM */ copy_data_sections(); /* Clear .bss sections */ clear_bss_sections(); /* Setup interrupt vector table */ setup_interrupt_vectors(); /* Enable interrupts */ __enable_irq(); /* Call C++ constructors */ call_cpp_constructors(); /* Jump to main */ main(); } /* Interrupt vectors */ void (*const vectors[])() __attribute__((section(“.vectors”))) = { (void (*)()) Reset_Handler, (void (*)()) other_interrupt_handlers }; /* .data section */ int initialized_var = 5; /* .bss section */ int bss_var; int main() { /* Application code here */ }

This shows the overall structure with the key startup code tasks needed to initialize the system and call main(). The exact implementation of each startup task would be specific to the particular ARM processor and development environment.

Key Startup Code Implementation Details

Some important aspects to note when implementing an ARM Cortex C startup code:

  • The Reset_Handler label must be placed at the very first address at the beginning of the startup code.
  • Low-level processor initialization is done first to setup core registers and clocks.
  • The interrupt vector table must be properly aligned on a suitable memory boundary.
  • Defined interrupt handlers can be weak symbols, allowing them to be overridden by the application.
  • The .data and .bss sections should be linked to appropriate linker script memory regions.
  • Static constructors are called before main(), invoked via the .init_array section.
  • Stack pointers and heap must be setup before calling main().

Toolchain Specific Startup Code

While the overall startup sequence remains similar across toolchains, the exact syntax and implementation do vary when using different compilers and libraries. For example:

GCC Startup Code

The GNU ARM Embedded Toolchain uses startup files like startup_ARMCMx.S, which implement common routines for Cortex-M processors. The SystemInit() call handles low-level processor initialization. Interrupt vectors are defined in handlers.c.

ARM Compiler Startup Code

The ARM Compiler provides the arm_startup_xxx.s files for Cortex-M processors, containing Reset_Handler and vector table.scatter files define memory regions. Low-level init can be done via SystemInit() or in asm code inside Reset_Handler.

IAR Startup Code

IAR Embedded Workbench utilizes files like startup_xxx.s specific to each Cortex-M processor. Reset_Handler performs low-level init. Interrupt vectors are defined in vector.s. Memory regions are in linker scatter files.

So while the overall startup sequence is standardized, check your toolchain documentation for exact syntax, file naming, and initialization details when creating a startup code.

Tips for ARM C Startup Code

Here are some useful tips when working with ARM Cortex C startup code:

  • Use stack protection and initialization to help catch issues early.
  • Debug and step through startup to verify configuration is as expected.
  • Add early initialization code before calling main() when needed.
  • Place startup code in own .c and .s files separate from main application.
  • Check compiler documentation for specific syntax and features.
  • Enable semihosting print debugging initially, then disable in production code.
  • Set up a non-maskable interrupt handler to help catch hard faults.

Conclusion

The C startup code performs the essential steps of initializing an ARM Cortex processor, configuring memory, enabling interrupts, and starting the application code. While the exact implementation varies across compilers and ARM chips, understanding the common patterns and sequences involved in a typical ARM C startup process allows developers to design robust embedded systems.

Key tasks like establishing the stack pointers, copying initialized data to RAM, clearing BSS sections, setting up the interrupt vectors, calling constructors, and jumping to main() provide the foundation for an ARM application. Following best practices around organization, low-level init, debugability, and overall startup structure helps ensure a successful program initialization sequence.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article What is the difference between ARM M4 and M55?
Next Article What is the SVC instruction in the arm cortex?
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

Software Development on Cortex-M1 Hardware Without an OS

Developing software directly on Cortex-M1 hardware without using an operating…

6 Min Read

Debugging Cortex-M0 DesignStart on non-ARM FPGAs

Using the Cortex-M0 DesignStart IP core on non-ARM partner FPGAs…

10 Min Read

Registering and Configuring the ARM MSP in Depth

The ARM Microcontroller Software Interface Standard (MSP) provides a standardized…

7 Min Read

Cortex-M1 address translation when accessing PS DDR memory

The Cortex-M1 processor implements a Memory Protection Unit (MPU) to…

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

Sign in to your account