What is Microcontrollers startup file – Understand its various Functions

In this tutorial, we will see the role of startup files in microcontrollers. Firstly, what is the startup file? and what exactly is the function of the startup file in bare-metal embedded systems? In the end, we will explore the startup file of ARM Cortex M4 microcontrollers and understand important sections of this file. Now let’s get started by defining a startup file.

What is a startup file in microcontrollers?

A startup file is a piece of code written in assembly or C language that executes before the main() function of our embedded application. It performs various initialization steps by setting up the hardware of the microcontroller so that the user application can run. Therefore, a startup file always runs before the main() code of our embedded application. 

The startup file performs various initializations and contains code for interrupt vector routines. As we have seen in the last tutorial when a microcontroller resets, it executes a reset handler (interrupt service routine) and performs hardware initialization before executing the main code. The startup file consists of this reset handler function and hardware initialization code. 

Functions of Startup file

Following are the main functions of a startup file:

  1. Disable all interrupts
  2. Copying initialized global, global static, and local static variable data from flash to .data section RAM memory of a microcontroller
  3. Copying uninitialized global, global static, and local static variable data from flash to .bss section of RAM memory and initialize .bss section of RAM to zero. 
  4. Allocate space for the stack and initialize the stack pointer
  5. It also contains an array of function pointers ( interrupt vector table) that point to various interrupt vector routines such as interrupts and exceptions. The startup file also contains definitions of these interrupt or exception routines such as reset handler, NMI handler, bus fault handler, etc.
  6. Enable interrupts
  7. Calls the main function 

Startup.s or startup.c file is architecture-dependent, especially the vector table part.

Understand the Startup file of TM4C123G Microcontrollers

Before understanding the startup file, let’s have a quick review of the vector table. TM4C123G microcontroller starting address of flash/code memory consists of a vector table and vector table values contains the addresses of interrupt or exception handlers. 

As shown in figure below, TM4C123GH6PM microcontroller has 15 exceptions and 138 IRQ interrupts. Therefore, the first 15+138 locations of code memory starting from 0x0000_0000 contain the address of exception and interrupt handlers. 

Microcontroller Booting Process Reset Sequence

Now let’s understand the startup file of TM4C123G microcontroller.  When we compile our application with Keil or any IDE, the startup file will be included automatically into our project. Keil IDE provides startup file in assembly language and code composer studio has a startup file available in c language. In this article, we will analyze the startup file of Keil compiler and it is available with the name of “startup_TM4C123.s”.

Microcontrollers startup file

Define Stack Area

Firstly, the startup file of TM4C123G microcontroller defines the stack area section and stack size in RAM memory. In this line, EQU is a assembler directive and it works similar to #define directive of c language. This line define a constant named “Stack_Size” with the value of 0x00000200.

Stack_Size      EQU     0x00000200

This line provides the declaration of the stack area. In assembly, AREA is an assembler directive that is used to define a different section of memory. In this line:

  • AREA: Used to define a new section
  • STACK: Name of the section
  • NOINT: It directs to initialize with stack memory with zero
  • READWRITE: This defines that the stack memory section has both read and write permission
  • ALIGN=3: Makes the starting of stack an 8-byte boundary
AREA    STACK, NOINIT, READWRITE, ALIGN=3

Here SPACE is assembler directive which is used to reserve space for the requested number of bytes. This line reserves 0x0400 bytes of memory to stack section.

Stack_Mem       SPACE   Stack_Size

Next, the __initial_sp label is used inside the vector table and it is used as a initial stack pointer.

Define Heap Area

These lines define the heap section and assign it space in memory similar to the stack memory area. Here __heap_base and __heap_limit define the starting and ending address of heap area.

Heap_Size       EQU     0x0000000
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

These line define the ARM Cortex M4 microcontroller mode of operation which is thumb mode and Cortex M4 microcontrollers only support thumb mode.

PRESERVE8
THUMB

Interrutp Vector table Array of function Pointers

Similar to C language, this assembly code create array of pointers which hold the address of initial stack pointer and addresses of a location which contains interrupt and exception handlers addresses.

Vector Table Mapped to Address 0 at Reset

                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

__Vectors       DCD     __initial_sp              ; Top of Stack
                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

                ; External Interrupts

                DCD     GPIOA_Handler             ;   0: GPIO Port A
                DCD     GPIOB_Handler             ;   1: GPIO Port B
                DCD     GPIOC_Handler             ;   2: GPIO Port C
                DCD     GPIOD_Handler             ;   3: GPIO Port D
                DCD     GPIOE_Handler             ;   4: GPIO Port E
                DCD     UART0_Handler             ;   5: UART0 Rx and Tx
                DCD     UART1_Handler             ;   6: UART1 Rx and Tx
                DCD     SSI0_Handler              ;   7: SSI0 Rx and Tx
                DCD     I2C0_Handler              ;   8: I2C0 Master and Slave
                DCD     PMW0_FAULT_Handler        ;   9: PWM Fault
                DCD     PWM0_0_Handler            ;  10: PWM Generator 0
                DCD     PWM0_1_Handler            ;  11: PWM Generator 1
                DCD     PWM0_2_Handler            ;  12: PWM Generator 2
                DCD     QEI0_Handler              ;  13: Quadrature Encoder 0
                DCD     ADC0SS0_Handler           ;  14: ADC Sequence 0
                DCD     ADC0SS1_Handler           ;  15: ADC Sequence 1
                DCD     ADC0SS2_Handler           ;  16: ADC Sequence 2
                DCD     ADC0SS3_Handler           ;  17: ADC Sequence 3
                DCD     WDT0_Handler              ;  18: Watchdog timer
                DCD     TIMER0A_Handler           ;  19: Timer 0 subtimer A
                DCD     TIMER0B_Handler           ;  20: Timer 0 subtimer B
                DCD     TIMER1A_Handler           ;  21: Timer 1 subtimer A
                DCD     TIMER1B_Handler           ;  22: Timer 1 subtimer B
                DCD     TIMER2A_Handler           ;  23: Timer 2 subtimer A
                DCD     TIMER2B_Handler           ;  24: Timer 2 subtimer B
                DCD     COMP0_Handler             ;  25: Analog Comparator 0
                DCD     COMP1_Handler             ;  26: Analog Comparator 1
                DCD     COMP2_Handler             ;  27: Analog Comparator 2
                DCD     SYSCTL_Handler            ;  28: System Control (PLL, OSC, BO)
                DCD     FLASH_Handler             ;  29: FLASH Control
                DCD     GPIOF_Handler             ;  30: GPIO Port F
                DCD     GPIOG_Handler             ;  31: GPIO Port G
                DCD     GPIOH_Handler             ;  32: GPIO Port H
                DCD     UART2_Handler             ;  33: UART2 Rx and Tx
                DCD     SSI1_Handler              ;  34: SSI1 Rx and Tx
                DCD     TIMER3A_Handler           ;  35: Timer 3 subtimer A
                DCD     TIMER3B_Handler           ;  36: Timer 3 subtimer B
                DCD     I2C1_Handler              ;  37: I2C1 Master and Slave
                DCD     QEI1_Handler              ;  38: Quadrature Encoder 1
                DCD     CAN0_Handler              ;  39: CAN0
                DCD     CAN1_Handler              ;  40: CAN1
                DCD     CAN2_Handler              ;  41: CAN2
                DCD     0                         ;  42: Reserved
                DCD     HIB_Handler               ;  43: Hibernate
                DCD     USB0_Handler              ;  44: USB0
                DCD     PWM0_3_Handler            ;  45: PWM Generator 3
                DCD     UDMA_Handler              ;  46: uDMA Software Transfer
                DCD     UDMAERR_Handler           ;  47: uDMA Error
                DCD     ADC1SS0_Handler           ;  48: ADC1 Sequence 0
                DCD     ADC1SS1_Handler           ;  49: ADC1 Sequence 1
                DCD     ADC1SS2_Handler           ;  50: ADC1 Sequence 2
                DCD     ADC1SS3_Handler           ;  51: ADC1 Sequence 3
                DCD     0                         ;  52: Reserved
                DCD     0                         ;  53: Reserved
                DCD     GPIOJ_Handler             ;  54: GPIO Port J
                DCD     GPIOK_Handler             ;  55: GPIO Port K
                DCD     GPIOL_Handler             ;  56: GPIO Port L
                DCD     SSI2_Handler              ;  57: SSI2 Rx and Tx
                DCD     SSI3_Handler              ;  58: SSI3 Rx and Tx
                DCD     UART3_Handler             ;  59: UART3 Rx and Tx
                DCD     UART4_Handler             ;  60: UART4 Rx and Tx
                DCD     UART5_Handler             ;  61: UART5 Rx and Tx
                DCD     UART6_Handler             ;  62: UART6 Rx and Tx
                DCD     UART7_Handler             ;  63: UART7 Rx and Tx
                DCD     0                         ;  64: Reserved
                DCD     0                         ;  65: Reserved
                DCD     0                         ;  66: Reserved
                DCD     0                         ;  67: Reserved
                DCD     I2C2_Handler              ;  68: I2C2 Master and Slave
                DCD     I2C3_Handler              ;  69: I2C3 Master and Slave
                DCD     TIMER4A_Handler           ;  70: Timer 4 subtimer A
                DCD     TIMER4B_Handler           ;  71: Timer 4 subtimer B
                DCD     0                         ;  72: Reserved
                DCD     0                         ;  73: Reserved
                DCD     0                         ;  74: Reserved
                DCD     0                         ;  75: Reserved
                DCD     0                         ;  76: Reserved
                DCD     0                         ;  77: Reserved
                DCD     0                         ;  78: Reserved
                DCD     0                         ;  79: Reserved
                DCD     0                         ;  80: Reserved
                DCD     0                         ;  81: Reserved
                DCD     0                         ;  82: Reserved
                DCD     0                         ;  83: Reserved
                DCD     0                         ;  84: Reserved
                DCD     0                         ;  85: Reserved
                DCD     0                         ;  86: Reserved
                DCD     0                         ;  87: Reserved
                DCD     0                         ;  88: Reserved
                DCD     0                         ;  89: Reserved
                DCD     0                         ;  90: Reserved
                DCD     0                         ;  91: Reserved
                DCD     TIMER5A_Handler           ;  92: Timer 5 subtimer A
                DCD     TIMER5B_Handler           ;  93: Timer 5 subtimer B
                DCD     WTIMER0A_Handler          ;  94: Wide Timer 0 subtimer A
                DCD     WTIMER0B_Handler          ;  95: Wide Timer 0 subtimer B
                DCD     WTIMER1A_Handler          ;  96: Wide Timer 1 subtimer A
                DCD     WTIMER1B_Handler          ;  97: Wide Timer 1 subtimer B
                DCD     WTIMER2A_Handler          ;  98: Wide Timer 2 subtimer A
                DCD     WTIMER2B_Handler          ;  99: Wide Timer 2 subtimer B
                DCD     WTIMER3A_Handler          ; 100: Wide Timer 3 subtimer A
                DCD     WTIMER3B_Handler          ; 101: Wide Timer 3 subtimer B
                DCD     WTIMER4A_Handler          ; 102: Wide Timer 4 subtimer A
                DCD     WTIMER4B_Handler          ; 103: Wide Timer 4 subtimer B
                DCD     WTIMER5A_Handler          ; 104: Wide Timer 5 subtimer A
                DCD     WTIMER5B_Handler          ; 105: Wide Timer 5 subtimer B
                DCD     FPU_Handler               ; 106: FPU
                DCD     0                         ; 107: Reserved
                DCD     0                         ; 108: Reserved
                DCD     I2C4_Handler              ; 109: I2C4 Master and Slave
                DCD     I2C5_Handler              ; 110: I2C5 Master and Slave
                DCD     GPIOM_Handler             ; 111: GPIO Port M
                DCD     GPION_Handler             ; 112: GPIO Port N
                DCD     QEI2_Handler              ; 113: Quadrature Encoder 2
                DCD     0                         ; 114: Reserved
                DCD     0                         ; 115: Reserved
                DCD     GPIOP0_Handler            ; 116: GPIO Port P (Summary or P0)
                DCD     GPIOP1_Handler            ; 117: GPIO Port P1
                DCD     GPIOP2_Handler            ; 118: GPIO Port P2
                DCD     GPIOP3_Handler            ; 119: GPIO Port P3
                DCD     GPIOP4_Handler            ; 120: GPIO Port P4
                DCD     GPIOP5_Handler            ; 121: GPIO Port P5
                DCD     GPIOP6_Handler            ; 122: GPIO Port P6
                DCD     GPIOP7_Handler            ; 123: GPIO Port P7
                DCD     GPIOQ0_Handler            ; 124: GPIO Port Q (Summary or Q0)
                DCD     GPIOQ1_Handler            ; 125: GPIO Port Q1
                DCD     GPIOQ2_Handler            ; 126: GPIO Port Q2
                DCD     GPIOQ3_Handler            ; 127: GPIO Port Q3
                DCD     GPIOQ4_Handler            ; 128: GPIO Port Q4
                DCD     GPIOQ5_Handler            ; 129: GPIO Port Q5
                DCD     GPIOQ6_Handler            ; 130: GPIO Port Q6
                DCD     GPIOQ7_Handler            ; 131: GPIO Port Q7
                DCD     GPIOR_Handler             ; 132: GPIO Port R
                DCD     GPIOS_Handler             ; 133: GPIO Port S
                DCD     PMW1_0_Handler            ; 134: PWM 1 Generator 0
                DCD     PWM1_1_Handler            ; 135: PWM 1 Generator 1
                DCD     PWM1_2_Handler            ; 136: PWM 1 Generator 2
                DCD     PWM1_3_Handler            ; 137: PWM 1 Generator 3
                DCD     PWM1_FAULT_Handler        ; 138: PWM 1 Fault

__Vectors_End

These lines dirtect to store this code in code/flash memory of microcontroller and __vectors location is defined inside the linker file and we will write about linker script file in coming tutorials.

__Vectors_Size  EQU     __Vectors_End - __Vectors

                AREA    |.text|, CODE, READONLY

Reset Handler Function

The startup file of microcontroller also contains rotines of interrupt and exceptions and reset handler function is one of them. This routine defines the reset handler function.

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP

For complete in-depth detail on how reset function of ARM Cortex microcontroller works, you can read this post:

Microcontrollers Booting Process

Other default Handlers

It also contains rountines of other exception and interrupt hanlders, but they are just a dumy routines executing while loop. But they are implemented with Weak attribute which makes it possible to redefine handler our own implementation of hanlders any where else in the project and we usually define our own handlers inside the main function.

Other related tutorials:

2 thoughts on “What is Microcontrollers startup file – Understand its various Functions”

  1. Hello,
    my comment on below point:
    “Copying uninitialized global, global static, and local static variable data from flash to .bss section of RAM memory and initialize .bss section of RAM to zero. ”
    :: need to copy from Flash as its value is zero so not stored on flash and in startup code after initialized data copied from flash to RAM then this uninitialized variables addresses are set to zero in RAM area and its address are already available from compiler directives. So simply use for loop from start address to end address to set value to uninitialized data.
    Please correct me if wrong.

    Reply

Leave a Comment