]> begriffs open source - cmsis/blob - CMSIS/Documentation/Doxygen/Core/src/using.md
Possible bugs in MMU_MemorySection(), MMU_MemoryPage() (#219)
[cmsis] / CMSIS / Documentation / Doxygen / Core / src / using.md
1 # Using CMSIS-Core {#using_pg}
2
3 [TOC]
4
5 To use the CMSIS-Core (Cortex-M) in an embedded software project at the following \ref cmsis_device_files need to be added to the application:
6
7  - \ref startup_c_pg with reset handler and exception vectors.
8  - \ref system_c_pg with general device configuration (i.e. for clock and BUS setup).
9  - \ref device_h_pg gives access to processor core and all peripherals.
10
11 ![Using CMSIS-Core (Cortex-M) in a project](./images/CMSIS_CORE_Files_USER.png)
12
13 The \ref startup_c_pg is executed after reset and calls `SystemInit()` in the reset hander. After the system initialization the 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 \ref startup_c_pg 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.
14
15 The \ref system_c_pg performs the setup for the processor clock. The variable \ref SystemCoreClock indicates the CPU clock speed. In addition the file may contain functions for the memory BUS setup and clock re-configuration.
16
17 > **Note**
18 > - The files \ref startup_c_pg and \ref system_c_pg may require application specific adaptations and therefore should be copied into the application project folder prior configuration.
19
20 The \ref device_h_pg provides access to the following device-specific functionalities:
21
22  - \ref peripheral_gr provides a standardized register layout for all peripherals. Optionally functions for device-specific peripherals may be available.
23  - \ref NVIC_gr can be accessed with standardized symbols and functions for the Nested Interrupt Vector Controller (NVIC) are provided.
24  - \ref intrinsic_CPU_gr allow to access special instructions, for example for activating sleep mode or the NOP instruction.
25  - \ref intrinsic_SIMD_gr provide access to the DSP-oriented instructions.
26  - \ref SysTick_gr function to configure and start a periodic timer interrupt.
27  - \ref ITM_Debug_gr are functions that allow printf-style I/O via the CoreSight Debug Unit and ITM communication.
28
29 ## Usage in CMSIS-Packs {#using_packs}
30
31 The easiest way to use CMSIS-Core in a project is with CMSIS Packs.
32
33 The \ref cmsis_device_files are typically provided in a [CMSIS Device Family Pack (DFP)](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/cp_PackTutorial.html#createPack_DFP) that is maintained by the chip vendor for the target device family. The list of public CMSIS packs (including DFPs) can be found at [keil.arm.com/packs](https://www.keil.arm.com/packs/).
34
35 A Device Family Pack (DFP) usually has a requirement for using the **CMSIS:CORE** component from the [CMSIS Software pack](../General/cmsis_pack.html) that contains the \ref cmsis_standard_files. In such case the CMSIS Software pack needs to be installed as well.
36
37 The files \ref startup_c_pg and \ref system_c_pg are typically provided in the DFP as part of **Device** class in the **Startup** group and are defined as configuration files, meaning they are copied from the pack into a project folder and can be modifed there if necessary.
38
39 The use of \ref device_h_pg can be abstracted with the `#define CMSIS_header_file` provided in [RTE_Components.h](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/cp_Packs.html#cp_RTECompH). This allows to have uniform include code in the application independent of the target device.
40
41 ```c
42 #include "RTE_Components.h"                      // include information about project configuration
43 #include CMSIS_device_header                     // include <Device>.h file
44 ```
45
46 Thereafter, the functions described under [API Reference](modules.html) can be used in the application.
47
48 For example, the following files are provided by the STM32F10x device family pack:
49
50 File                         | Description
51 :---------------------------------|:------------------------------------------------------------------------
52 ".\Device\Source\ARM\startup_stm32f10x_cl.s" | \ref startup_c_pg for the STM32F10x device variants
53 ".\Device\Source\system_stmf10x.c"  | \ref system_c_pg for the STM32F10x device families
54 ".\Device\Include\stm32f10x.h"      | \ref device_h_pg for the STM32F10x device families
55
56 \ref cmsis_files_dfps provides more information on how CMSIS-Core files can be delivered in CMSIS Packs.
57
58 ## Usage Examples {#usage_examples}
59
60 **Examples**
61
62  - \ref using_basic is a simple example that shows the usage of the CMSIS layer.
63  - \ref using_vtor shows how to remap the interrupt vector table.
64  - \ref using_arm explains how to use CMSIS-Core (Cortex-M) for Arm processors.
65  - \ref using_ARM_Lib_sec explains how to create libraries that support various Cortex-M cores.
66
67 Also see \ref using_TrustZone_pg that details CMSIS-Core support for Arm TrusZone operation on Cortex-M.
68
69 ### Basic CMSIS Example {#using_basic}
70
71 A typical example for using the CMSIS layer is provided below. The example is based on a STM32F10x Device.
72
73 ```c
74 #include <stm32f10x.h>                           // File name depends on device used
75  
76 uint32_t volatile msTicks;                       // Counter for millisecond Interval
77  
78 void SysTick_Handler (void) {                    // SysTick Interrupt Handler
79   msTicks++;                                     // Increment Counter
80 }
81  
82 void WaitForTick (void)  {
83   uint32_t curTicks;
84  
85   curTicks = msTicks;                            // Save Current SysTick Value
86   while (msTicks == curTicks)  {                 // Wait for next SysTick Interrupt
87     __WFE ();                                    // Power-Down until next Event/Interrupt
88   }
89 }
90  
91 void TIM1_UP_IRQHandler (void) {                 // Timer Interrupt Handler
92   ;                                              // Add user code here
93 }
94  
95 void timer1_init(int frequency) {                // Set up Timer (device specific)
96   NVIC_SetPriority (TIM1_UP_IRQn, 1);            // Set Timer priority
97   NVIC_EnableIRQ (TIM1_UP_IRQn);                 // Enable Timer Interrupt
98 }
99  
100  
101 void Device_Initialization (void)  {             // Configure & Initialize MCU
102   if (SysTick_Config (SystemCoreClock / 1000)) { // SysTick 1mSec
103        : // Handle Error 
104   }
105   timer1_init ();                                // setup device-specific timer
106 }
107  
108  
109 // The processor clock is initialized by CMSIS startup + system file
110 void main (void) {                               // user application starts here
111   Device_Initialization ();                      // Configure & Initialize MCU
112   while (1)  {                                   // Endless Loop (the Super-Loop)
113     __disable_irq ();                            // Disable all interrupts
114     Get_InputValues ();                          // Read Values
115     __enable_irq ();                             // Enable all interrupts 
116     Calculation_Response ();                     // Calculate Results
117     Output_Response ();                          // Output Results
118     WaitForTick ();                              // Synchronize to SysTick Timer
119   }
120 }
121 ```
122
123 ### Using Interrupt Vector Remap {#using_vtor}
124
125 Most Cortex-M processors provide VTOR register for remapping interrupt vectors. The following example shows a typical use case where the interrupt vectors are copied to RAM and the `SysTick_Handler` is replaced.
126
127 ```c
128 #include "ARMCM3.h"                     // Device header
129  
130 #define VECTORTABLE_SIZE        (240)    /* size of the used vector tables    */
131                                          /* see startup file startup_ARMCM3.c */
132 #define VECTORTABLE_ALIGNMENT   (0x100U) /* 16 Cortex + 32 ARMCM3 = 48 words  */
133                                          /* next power of 2 = 256             */
134
135 /* externals from startup_ARMCM3.c */
136 extern uint32_t __VECTOR_TABLE[VECTORTABLE_SIZE];        /* vector table ROM  */
137
138 /* new vector table in RAM, same size as vector table in ROM */
139 uint32_t vectorTable_RAM[VECTORTABLE_SIZE] __attribute__(( aligned (VECTORTABLE_ALIGNMENT) ));
140
141  
142 /*----------------------------------------------------------------------------
143   SysTick_Handler
144  *----------------------------------------------------------------------------*/
145 volatile uint32_t msTicks = 0;                        /* counts 1ms timeTicks */
146 void SysTick_Handler(void) {
147   msTicks++;                                             /* increment counter */
148 }
149  
150 /*----------------------------------------------------------------------------
151   SysTick_Handler (RAM)
152  *----------------------------------------------------------------------------*/
153 volatile uint32_t msTicks_RAM = 0;                    /* counts 1ms timeTicks */
154 void SysTick_Handler_RAM(void) {
155   msTicks_RAM++;                                      /* increment counter */
156 }
157  
158 /*----------------------------------------------------------------------------
159   MAIN function
160  *----------------------------------------------------------------------------*/
161 int main (void) {
162   uint32_t i;
163    
164   for (i = 0; i < VECTORTABLE_SIZE; i++) {
165     vectorTable_RAM[i] = __VECTOR_TABLE[i];       /* copy vector table to RAM */
166   }
167                                                    /* replace SysTick Handler */
168   vectorTable_RAM[SysTick_IRQn + 16] = (uint32_t)SysTick_Handler_RAM;
169   
170   /* relocate vector table */ 
171   __disable_irq();
172     SCB->VTOR = (uint32_t)&vectorTable_RAM;
173   __DSB();
174   __enable_irq();
175  
176   SystemCoreClockUpdate();                        /* Get Core Clock Frequency */
177   SysTick_Config(SystemCoreClock / 1000ul); /* Setup SysTick Timer for 1 msec */
178    
179   while(1);
180 }
181 ```
182
183 ### Use generic Arm Devices {#using_arm}
184
185 Test and example projects of many software components have a need for implementations that are independent from specific device vendors but still have adaptations for various Arm Cortex-M cores to benefit from their architectural differenceis.
186
187 The [Cortex_DFP pack](https://github.com/ARM-software/Cortex_DFP) provides generic device definitions for standard Arm Cortex-M cores and contains corresponding \ref cmsis_device_files. These generic Arm devices can be used as a target for embedded programs, with execution, for example, on processor simulation models.
188
189 Validation suits and example projects for such components as [CMSIS-DSP](../DSP/index.html), [CMSIS-RTOS](../RTOS2/index.html) and [CMSIS-Core](index.html) itself use that approach already.
190
191 ### Create generic libraries {#using_ARM_Lib_sec}
192
193 The CMSIS Processor and Core Peripheral files allow also to create generic libraries. 
194 The [CMSIS-DSP libraries](../DSP/index.html) are an example for such a generic library.
195
196 To build a generic Library set the define `__CMSIS_GENERIC` and include the relevant `core_<cpu>.h` CMSIS CPU & Core Access header file for the processor.
197
198 The define `__CMSIS_GENERIC` disables device-dependent features such as the **SysTick** timer and the **Interrupt System**.
199
200 Refer to \ref core_config_sect for a list of the available `core_<cpu>.h` header files.
201
202 **Example:**
203
204 The following code section shows the usage of the `core_<cpu>.h` header files to build a generic library for Cortex-M0, Cortex-M3, Cortex-M4, or Cortex-M7 devices.
205
206 To select the processor, the source code uses the defines `CORTEX_M7`, `CORTEX_M4`, `CORTEX_M3`, `CORTEX_M0`, or `CORTEX_M0PLUS`. One of these defines needs to be provided on the compiler command line. By using this header file, the source code can access the correct implementations for \ref Core_Register_gr, \ref intrinsic_CPU_gr, \ref intrinsic_SIMD_gr, and \ref ITM_Debug_gr.
207
208 ```c
209 #define __CMSIS_GENERIC              /* disable NVIC and Systick functions */
210
211 #if defined (CORTEX_M7)
212   #include "core_cm7.h"
213 #elif defined (CORTEX_M4)
214   #include "core_cm4.h"
215 #elif defined (CORTEX_M3)
216   #include "core_cm3.h"
217 #elif defined (CORTEX_M0)
218   #include "core_cm0.h"
219 #elif defined (CORTEX_M0PLUS)
220   #include "core_cm0plus.h"
221 #else
222   #error "Processor not specified or unsupported."
223 #endif
224 ```