CMSIS-Core (Cortex-M): Startup File startup_\<device\>.c

| CMSIS-Core (Cortex-M) Version 5.6.0 CMSIS-Core support for Cortex-M processor-based devices

- Main Page
- Usage and Description
- Reference

All Data Structures Files Functions Variables Enumerations Enumerator Groups Pages
Startup File startup_<device>.c

The Startup File startup_<device>.c contains:

- The reset handler which is executed after CPU reset and typically calls the SystemInit function.
- The setup values for the Main Stack Pointer (MSP).
- Exception vectors of the Cortex-M Processor with weak functions that implement default routines.
- Interrupt vectors that are device specific with weak functions that implement default routines.

The file exists for each supported toolchain and is the only tool-chain specific CMSIS file.

To adapt the file to a new device only the interrupt vector table needs to be extended with the device-specific interrupt handlers. The naming convention for the interrupt handler names are <interrupt_name>_IRQHandler. This table needs to be consistent with IRQn_Type that defines all the IRQ numbers for each interrupt.

Example:

The following example shows the extension of the interrupt vector table for the LPC1100 device family.

/*----------------------------------------------------------------------------
Exception / Interrupt Handler
*----------------------------------------------------------------------------*/
/* Exceptions */
void WAKEUP0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void WAKEUP1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void WAKEUP2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
// :
// :
void EINT1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void EINT2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
// :
// :
/*----------------------------------------------------------------------------
Exception / Interrupt Vector table
*----------------------------------------------------------------------------*/
extern const pFunc __VECTOR_TABLE[240];
const pFunc __VECTOR_TABLE[240] __VECTOR_TABLE_ATTRIBUTE = {
(pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */
Reset_Handler, /* Reset Handler */
NMI_Handler, /* -14 NMI Handler */
HardFault_Handler, /* -13 Hard Fault Handler */
MemManage_Handler, /* -12 MPU Fault Handler */
BusFault_Handler, /* -11 Bus Fault Handler */
UsageFault_Handler, /* -10 Usage Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* -5 SVC Handler */
DebugMon_Handler, /* -4 Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* -2 PendSV Handler */
SysTick_Handler, /* -1 SysTick Handler */
/* Interrupts */
WAKEUP0_IRQHandler, /* 0 Wakeup PIO0.0 */
WAKEUP1_IRQHandler, /* 1 Wakeup PIO0.1 */
WAKEUP2_IRQHandler, /* 2 Wakeup PIO0.2 */
// :
// :
EINT1_IRQHandler, /* 30 PIO INT1 */
EINT2_IRQHandler, /* 31 PIO INT2 */
// :
// :
};

# startup_Device.c Template File

A compiler agnostic startup_Device.c Template File for an Armv7-M processor like Cortex-M3 is shown below. The C startup file relys on certain compiler specific preprocessor defines specified in CMSIS compiler headers:

- __INITIAL_SP
- __STACK_LIMIT
- __PROGRAM_START
- __VECTOR_TABLE
- __VECTOR_TABLE_ATTRIBUTE

    /******************************************************************************
     * @file     startup_<Device>.c
     * @brief    CMSIS-Core(M) Device Startup File for
     *           Device <Device>
     * @version  V1.0.0
     * @date     20. January 2021
     ******************************************************************************/
    /*
     * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
     *
     * SPDX-License-Identifier: Apache-2.0
     *
     * Licensed under the Apache License, Version 2.0 (the License); you may
     * not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an AS IS BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    #include "<Device>.h"

    /*---------------------------------------------------------------------------
      External References
     *---------------------------------------------------------------------------*/
    extern uint32_t __INITIAL_SP;
    extern uint32_t __STACK_LIMIT;
    #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
    extern uint32_t __STACK_SEAL;
    #endif

    extern __NO_RETURN void __PROGRAM_START(void);

    /*---------------------------------------------------------------------------
      Internal References
     *---------------------------------------------------------------------------*/
    __NO_RETURN void Reset_Handler  (void);
    __NO_RETURN void Default_Handler(void);

    /* ToDo: Add Cortex exception handler according the used Cortex-Core */
    /*---------------------------------------------------------------------------
      Exception / Interrupt Handler
     *---------------------------------------------------------------------------*/
    /* Exceptions */
    void NMI_Handler            (void) __attribute__ ((weak, alias("Default_Handler")));
    void HardFault_Handler      (void) __attribute__ ((weak));
    void MemManage_Handler      (void) __attribute__ ((weak, alias("Default_Handler")));
    void BusFault_Handler       (void) __attribute__ ((weak, alias("Default_Handler")));
    void UsageFault_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
    void SecureFault_Handler    (void) __attribute__ ((weak, alias("Default_Handler")));
    void SVC_Handler            (void) __attribute__ ((weak, alias("Default_Handler")));
    void DebugMon_Handler       (void) __attribute__ ((weak, alias("Default_Handler")));
    void PendSV_Handler         (void) __attribute__ ((weak, alias("Default_Handler")));
    void SysTick_Handler        (void) __attribute__ ((weak, alias("Default_Handler")));

    /* ToDo: Add your device specific interrupt handler */
    void <DeviceInterrupt first>_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
    ...
    void <DeviceInterrupt last>_Handler      (void) __attribute__ ((weak, alias("Default_Handler")));

    /*----------------------------------------------------------------------------
      Exception / Interrupt Vector table
     *----------------------------------------------------------------------------*/

    #if defined ( __GNUC__ )
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wpedantic"
    #endif

    /* ToDo: Add Cortex exception vectors according the used Cortex-Core */
    extern const VECTOR_TABLE_Type __VECTOR_TABLE[<Device vector table entries>];
           const VECTOR_TABLE_Type __VECTOR_TABLE[<Device vector table entries>] __VECTOR_TABLE_ATTRIBUTE = {
      (VECTOR_TABLE_Type)(&__INITIAL_SP),  /*     Initial Stack Pointer */
      Reset_Handler,                       /*     Reset Handler */
      NMI_Handler,                         /* -14 NMI Handler */
      HardFault_Handler,                   /* -13 Hard Fault Handler */
      MemManage_Handler,                   /* -12 MPU Fault Handler */
      BusFault_Handler,                    /* -11 Bus Fault Handler */
      UsageFault_Handler,                  /* -10 Usage Fault Handler */
      SecureFault_Handler,                 /*  -9 Secure Fault Handler */
      0,                                   /*     Reserved */
      0,                                   /*     Reserved */
      0,                                   /*     Reserved */
      SVC_Handler,                         /*  -5 SVCall Handler */
      DebugMon_Handler,                    /*  -4 Debug Monitor Handler */
      0,                                   /*     Reserved */
      PendSV_Handler,                      /*  -2 PendSV Handler */
      SysTick_Handler,                     /*  -1 SysTick Handler */

    /* ToDo: Add your device specific interrupt vectors */
      /* Interrupts */
      <DeviceInterrupt first>_Handler,     /* first Device Interrupt */
      ...
      <DeviceInterrupt last>_Handler       /* last Device Interrupt */
    };

    #if defined ( __GNUC__ )
    #pragma GCC diagnostic pop
    #endif

    /*---------------------------------------------------------------------------
      Reset Handler called on controller reset
     *---------------------------------------------------------------------------*/
    __NO_RETURN void Reset_Handler(void)
    {
      __set_PSP((uint32_t)(&__INITIAL_SP));

    /* ToDo: Initialize stack limit register for Armv8-M Main Extension based processors*/
      __set_MSPLIM((uint32_t)(&__STACK_LIMIT));
      __set_PSPLIM((uint32_t)(&__STACK_LIMIT));

    /* ToDo: Add stack sealing for Armv8-M based processors */
    #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
      __TZ_set_STACKSEAL_S((uint32_t *)(&__STACK_SEAL));
    #endif

      SystemInit();                    /* CMSIS System Initialization */
      __PROGRAM_START();               /* Enter PreMain (C library entry point) */
    }

    #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
      #pragma clang diagnostic push
      #pragma clang diagnostic ignored "-Wmissing-noreturn"
    #endif

    /*---------------------------------------------------------------------------
      Hard Fault Handler
     *---------------------------------------------------------------------------*/
    void HardFault_Handler(void)
    {
      while(1);
    }

    /*---------------------------------------------------------------------------
      Default Handler for Exceptions / Interrupts
     *---------------------------------------------------------------------------*/
    void Default_Handler(void)
    {
      while(1);
    }

    #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
      #pragma clang diagnostic pop
    #endif

# startup_Device.c Template File (Armv8-M/v8.1-M)

The C-startup file for an Armv8-M/v8.1-M processor is similar to the one for an Armv7-M processor except that it offers the possibility of stack sealing for the Main Stack Pointer (MSP). The following preprocessor defines and CMSIS functions are used:

- __STACK_SEAL
- __TZ_set_STACKSEAL_S

The stack sealing and the initialization fof the Stack Limit register is done in function void Reset_Handler(void):

/*----------------------------------------------------------------------------
Reset Handler called on controller reset
*----------------------------------------------------------------------------*/
__NO_RETURN void Reset_Handler(void)
{
__set_PSP((uint32_t)(&__INITIAL_SP));
__set_MSPLIM((uint32_t)(&__STACK_LIMIT));
__set_PSPLIM((uint32_t)(&__STACK_LIMIT));
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
__TZ_set_STACKSEAL_S((uint32_t *)(&__STACK_SEAL));
#endif
SystemInit(); /* CMSIS System Initialization */
__PROGRAM_START(); /* Enter PreMain (C library entry point) */
}

Note
  Stack Sealing also requires the application project to use a scatter file (or a linker script) as explained in Stack Sealing section.