CMSIS v6 supports the following toolchains:
Before migrating your project, please make sure that you use one of these toolchains. In this learning path, you will use the Arm Compiler for Embedded v6 toolchain.
To update the device support, you will need to follow the steps outlined below:
In CMSIS v6, assembly-based startup code is deprecated. You must move your startup_device.s
files to startup_device.c
. This section explains the necessary steps.
Copy the startup_ARMCMx.c
file from the
CMSIS-DFP repo
into your device support repo. In this example, a Cortex-M4-based device is used (and therefore, the
startup_ARMCM4.c
is taken from CMSIS-DFP/Device/ARMCM4/source).
Copy all the interrupt handler names and wrap them into void handler_name (void) __attribute__ ((weak, alias("Default_Handler")));
. Place them around line 58 of the template file.
Code Example
; Interrupt Handlers for Service Requests (SR) from Peripherals */
Entry SCU_0_IRQHandler ; Handler name for SR SCU_0
Entry ERU0_0_IRQHandler ; Handler name for SR ERU0_0
Entry ERU0_1_IRQHandler ; Handler name for SR ERU0_1
Entry ERU0_2_IRQHandler ; Handler name for SR ERU0_2
Entry ERU0_3_IRQHandler ; Handler name for SR ERU0_3
Entry ERU1_0_IRQHandler ; Handler name for SR ERU1_0
Entry ERU1_1_IRQHandler ; Handler name for SR ERU1_1
Entry ERU1_2_IRQHandler ; Handler name for SR ERU1_2
Entry ERU1_3_IRQHandler ; Handler name for SR ERU1_3
DCD 0 ; Not Available
DCD 0 ; Not Available
DCD 0 ; Not Available
Entry PMU0_0_IRQHandler ; Handler name for SR PMU0_0
DCD 0 ; Not Available
Entry VADC0_C0_0_IRQHandler ; Handler name for SR VADC0_C0_0
Entry VADC0_C0_1_IRQHandler ; Handler name for SR VADC0_C0_1
Entry VADC0_C0_2_IRQHandler ; Handler name for SR VADC0_C0_1
Entry VADC0_C0_3_IRQHandler ; Handler name for SR VADC0_C0_3
Translates to:
void SCU_0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU0_0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU0_1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU0_2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU0_3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU1_0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU1_1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU1_2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void ERU1_3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void PMU0_0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void VADC0_C0_0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void VADC0_C0_1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void VADC0_C0_2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
void VADC0_C0_3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
Copy the list of names with the empty handlers to the __VECTOR_TABLE_ATTRIBUTE
separated by commas (around line 99 in the template). Starting from the same assembly exception list as in the previous point, this translates to:
extern const VECTOR_TABLE_Type __VECTOR_TABLE[240];
const VECTOR_TABLE_Type __VECTOR_TABLE[240] __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 */
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 */
SCU_0_IRQHandler,
ERU0_0_IRQHandler,
ERU0_1_IRQHandler,
ERU0_2_IRQHandler,
ERU0_3_IRQHandler,
ERU1_0_IRQHandler,
ERU1_1_IRQHandler,
ERU1_2_IRQHandler,
ERU1_3_IRQHandler,
0,
0,
0,
PMU0_0_IRQHandler,
0,
VADC0_C0_0_IRQHandler,
VADC0_C0_1_IRQHandler,
VADC0_C0_2_IRQHandler,
VADC0_C0_3_IRQHandler
/* Further interrupts are left out */
};
Make sure that additional functions (boot code
, for example) are implemented in C.
If you have conditional assembly, replace it with conditional compilation:
Code Example
IF (USE_CHIP=SOME_CHIP)
DCD WDT_IRQHandler
ELSE
DCD _RESERVED
ENDIF
Translates to:
#if (USE_CHIP=SOME_CHIP)
WDT_IRQHandler,
#else
0,
#endif
Save your new startup_device.c
file. If you have entries for stack and heap size in the assembly startup file, save these and add them in the next step to the now mandatory scatter file.
Copy the scatter file template from the CMSIS-DFP repo into your device support repo. The scatter file template for the Cortex-M4 is called ARMCM4_ac6.sct .
Edit the template according to your device settings. These values need to be set:
#define __ROM_BASE 0x00000000
#define __ROM_SIZE 0x00080000
#define __RAM_BASE 0x20000000
#define __RAM_SIZE 0x00040000
#define __STACK_SIZE 0x00000200
#define __HEAP_SIZE 0x00000C00
startup_device.s
file with the new startup_device.c
file and add the device’s scatter file as follows:
<!-- startup / system / scatter files -->
<file category="sourceC" name="path/to/startup_device.c" version="1.0.1" attr="config"/>
<file category="linkerScript" name="path/to/device_ac6.sct" version="1.0.0" attr="config" condition="ARMCC6"/>