Using CMSIS in Embedded Applications

| CMSIS-CORE Version 3.01 CMSIS-CORE support for Cortex-M processor-based devices

- CMSIS
- CORE
- DSP
- RTOS API
- SVD

- Main Page
- Usage and Description
- Reference

Using CMSIS in Embedded Applications

To use the CMSIS-CORE the following files are added to the embedded application:

- Startup File startup_<device>.s with reset handler and exception vectors.
- System Configuration Files system_<device>.c and system_<device>.h with general device configuration (i.e. for clock and BUS setup).
- Device Header File <device.h> gives access to processor core and all peripherals.

Note:
  The files Startup File startup_<device>.s and System Configuration Files system_<device>.c and system_<device>.h may require application specific adaptations and therefore should be copied into the application project folder prior configuration. The Device Header File <device.h> is included in all source files that need device access and can be stored on a central include folder that is generic for all projects.

The Startup File startup_<device>.s is executed after reset and calls SystemInit. After the system initialization control is transferred to the C/C++ run-time library which performs initialization and calls the main function in the user code. In addition the Startup File startup_<device>.s contains all exception and interrupt vectors and implements a default function for every interrupt. It may also contain stack and heap configurations for the user application.

The System Configuration Files system_<device>.c and system_<device>.h performs the setup for the processor clock. The variable SystemCoreClock indicates the CPU clock speed. System and Clock Configuration describes the minimum feature set. In addition the file may contain functions for the memory BUS setup and clock re-configuration.

The Device Header File <device.h> is the central include file that the application programmer is using in the C source code. It provides the following features:

- Peripheral Access provides a standardized register layout for all peripherals. Optionally functions for device-specific peripherals may be available.
- Interrupts and Exceptions (NVIC) can be accessed with standardized symbols and functions for the Nested Interrupt Vector Controller (NVIC) are provided.
- Intrinsic Functions for CPU Instructions allow to access special instructions, for example for activating sleep mode or the NOP instruction.
- Intrinsic Functions for SIMD Instructions [only Cortex-M4] provide access to the DSP-oriented instructions.
- Systick Timer (SYSTICK) function to configure and start a periodic timer interrupt.
- Debug Access are functions that allow printf-style I/O via the CoreSight Debug Unit and ITM communication.

CMSIS-CORE User Files

The CMSIS-CORE are device specific. In addition, the Startup File startup_<device>.s is also compiler vendor specific. The various compiler vendor tool chains may provide folders that contain the CMSIS files for each supported device. Using CMSIS with generic ARM Processors explains how to use CMSIS-CORE for ARM processors.

For example, the following files are provided in MDK-ARM to support the STM32F10x Connectivity Line device variants:

File | Description
--- | ---
".\ARM\Startup\ST\STM32F10x\startup_stm32f10x_cl.s" | Startup File startup_<device>.s for the STM32F10x Connectivity Line device variants.
".\ARM\Startup\ST\STM32F10x\system_stmf10x.c" | System Configuration Files system_<device>.c and system_<device>.h for the STM32F10x device families.
".\ARM\INC\ST\STM32F10x\stm32f10x.h" | Device Header File <device.h> for the STM32F10x device families.
".\ARM\INC\ST\STM32F10x\system_stm32f10x.h" | system_Device.h Template File for the STM32F10x device families.

Note:
  The silicon vendors create these device-specific CMSIS-CORE files based on Template Files provide by ARM.

Thereafter, the functions described under Reference can be used in the application.

A typical example for using the CMSIS layer is provided below. The example is based on a STM32F10x Device.

    #include <stm32f10x.h>                           // File name depends on device used

    uint32_t volatile msTicks;                       // Counter for millisecond Interval

    void SysTick_Handler (void) {                    // SysTick Interrupt Handler
      msTicks++;                                     // Increment Counter
    }

    void WaitForTick (void)  {
      uint32_t curTicks;

      curTicks = msTicks;                            // Save Current SysTick Value
      while (msTicks == curTicks)  {                 // Wait for next SysTick Interrupt
        __WFE ();                                    // Power-Down until next Event/Interrupt
      }
    }

    void TIM1_UP_IRQHandler (void) {                 // Timer Interrupt Handler
      ;                                              // Add user code here
    }

    void timer1_init(int frequency) {                // Set up Timer (device specific)
      NVIC_SetPriority (TIM1_UP_IRQn, 1);            // Set Timer priority
      NVIC_EnableIRQ (TIM1_UP_IRQn);                 // Enable Timer Interrupt
    }

    void Device_Initialization (void)  {             // Configure & Initialize MCU
      if (SysTick_Config (SystemCoreClock / 1000)) { // SysTick 1mSec
           : // Handle Error
      }
      timer1_init ();                                // setup device-specific timer
    }

    // The processor clock is initialized by CMSIS startup + system file
    void main (void) {                                   // user application starts here
      Device_Initialization ();                      // Configure & Initialize MCU
      while (1)  {                                   // Endless Loop (the Super-Loop)
        __disable_irq ();                            // Disable all interrupts
        Get_InputValues ();                          // Read Values
        __enable_irq ();                             // Enable all interrupts
        Calculation_Response ();                     // Calculate Results
        Output_Response ();                          // Output Results
        WaitForTick ();                              // Synchronize to SysTick Timer
      }
    }