ARM-Cortex-M Porting Guide
6 minute read
Overview
XWOS source code already includes most of the ARM-Cortex-M architecture code:
- Architecture Description Layer (ADL)
- ARMv7m:
XWOS/xwcd/soc/arm/v7m - ARMv6m:
XWOS/xwcd/soc/arm/v6m
- ARMv7m:
- CPU Description Layer (CDL)
- m0:
XWOS/xwcd/soc/arm/v6m/m0 - m0p:
XWOS/xwcd/soc/arm/v6m/m0p - m3:
XWOS/xwcd/soc/arm/v7m/m3 - m4:
XWOS/xwcd/soc/arm/v7m/m4 - m7:
XWOS/xwcd/soc/arm/v7m/m7
- m0:
- SoC Description Layer (SDL)
- STM32:
- L0/F0:
XWOS/xwcd/soc/arm/v7m/m0/stm32 - L1/F1:
XWOS/xwcd/soc/arm/v7m/m3/stm32 - L4/F4:
XWOS/xwcd/soc/arm/v7m/m4/stm32- F7/H7:
XWOS/xwcd/soc/arm/v7m/m7/stm32
- F7/H7:
- L0/F0:
- S32K:
XWOS/xwcd/soc/arm/v7m/m4/s32k14x - i.MX RT1052:
XWOS/xwcd/soc/arm/v7m/m7/mimxrt1052
- STM32:
For a new SoC chip, you only need to add an SoC folder in the CPU folder, which includes:
- Initialization:
soc_init.handsoc_init.c - Interrupts:
xwosimpl_irq.handxwosimpl_irq.c- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
XWOS/xwos/ospl/irq.h.
- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
- Scheduler:
xwosimpl_skd.handxwosimpl_skd.c- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
XWOS/xwos/ospl/skd.h.
- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
- Tick Timer:
xwosimpl_syshwt.handxwosimpl_syshwt.c- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
XWOS/xwos/ospl/syshwt.h.
- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
.lds: Linker script
You can copy an SDL folder (e.g., STM32) as a template.
All Cortex-M microcontrollers share the same XWOSIMPL.
Type Definitions
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_type.h
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_type.h
Compiler Macro Definitions
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_compiler.h
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_compiler.h
Lock-Free Queue Implementation
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_lfq.h
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_lfq.c
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_lfq.h
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_lfq.c
Spinlock
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_spinlock.h
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_spinlock.h
Architecture Instructions
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_isa.h
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_isa.h
Bit Operations
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwbop
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwbop
8-bit Atomic Operations
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xws8/
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xwu8/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xws8/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xwu8/
16-bit Atomic Operations
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xws16/
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xwu16/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xws16/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xwu16/
32-bit Atomic Operations
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xws32/
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xwu32/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xws32/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xwu32/
64-bit Atomic Operations
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xws64/
XWOS/xwcd/soc/arm/v6m/xwosimpl_arch_xwaop/xwu64/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xws64/
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_xwaop/xwu64/
setjmp()/longjmp()
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_setjmp.h
XWOS/xwcd/soc/arm/v7m/xwosimpl_arch_setjmp.c
The setjmp()/longjmp() defined in the C standard library are goto statements that can jump between different functions.
Some libc implementations do not consider the floating-point register stack, so XWOS has re-implemented these two functions.
- The complete stack layout is as follows:
-----------------------------
sp+0x64 | s31 | |
sp+0x60 | s30 | |
sp+0x5C | s29 | |
sp+0x58 | s28 | |
sp+0x54 | s27 | |
sp+0x50 | s26 | |
sp+0x4C | s25 | FP |
sp+0x48 | s24 | Frame |
sp+0x44 | s23 | |
sp+0x40 | s22 | |
sp+0x3C | s21 | |
sp+0x38 | s20 | |
sp+0x34 | s19 | |
sp+0x30 | s18 | |
sp+0x2C | s17 | |
sp+0x28 | s16 | |
-----------------------------
sp+0x24 | r14 (lr) | |
sp+0x20 | r13 (sp) | |
sp+0x1C | r11 (fp) | |
sp+0x18 | r10 (sl) | |
sp+0x14 | r9 | Basic |
sp+0x10 | r8 | Frame |
sp+0x0C | r7 | |
sp+0x08 | r6 | |
sp+0x04 | r5 | |
sp+0x00 | r4 | |
-----------------------------
setjmp/longjmp Register Stack Layout
Thread Local Storage (TLS)
TLS is a language feature introduced starting from the C11 standard. XWOS supports TLS, and Cortex-M MCUs use a unified implementation:
XWOS/xwcd/soc/arm/v6m/xwosimpl_tls.c
XWOS/xwcd/soc/arm/v7m/xwosimpl_tls.c
XWOS places the TLS data section at the start of the thread stack memory.
------------------------
| Thread Stack Memory |
+----------------------+
SP ---> | |
| |
| |
| |
| |
| |
| Stack Region |
| |
| |
| |
| |
| |
| |
+----------------------+
| |
| Stack Guard |
| |
+----------------------+
| |
| TLS Region |
| |
------------------------
Scheduler
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v6m/[CPU]/[SoC]/xwosimpl_arch_skd.h
XWOS/xwcd/soc/arm/v6m/[CPU]/[SoC]/xwosimpl_arch_skd.c
XWOS/xwcd/soc/arm/v7m/[CPU]/[SoC]/xwosimpl_arch_skd.h
XWOS/xwcd/soc/arm/v7m/[CPU]/[SoC]/xwosimpl_arch_skd.c
Due to the good consistency of Cortex-M core microcontrollers, different microcontrollers ultimately call functions in the following files to provide specific implementations:
XWOS/xwcd/soc/arm/v6m/arch_skd.h
XWOS/xwcd/soc/arm/v6m/arch_skd.c
XWOS/xwcd/soc/arm/v7m/arch_skd.h
XWOS/xwcd/soc/arm/v7m/arch_skd.c
Thread Stack
- On ARMv6/7-m platforms, XWOS uses an 8-byte aligned stack, therefore STKALIGN in the CCR register must be set to 1 at the earliest stage of chip initialization:
cm_scs.scb.ccr.bit.stkalign = 1;
- A full descending stack is used, meaning
XWMMCFG_FD_STACKin the configuration filecfg/xwos.his configured as 1. - When the CPU includes a floating-point unit, enable automatic floating-point context saving and restoring via:
cm_scs.scb.fpu.fpccr.bit.aspen = 1;
Thread Stack Layout
In C, registers are generally divided into two types: volatile and non-volatile. When volatile registers are used, their values do not need to be saved and restored; when non-volatile registers are used, their values need to be saved and restored.
Volatile Stack Layout
On ARMv6/v7-m CPUs, when entering interrupt mode from thread mode, volatile registers are automatically saved to the stack.
------------------------
| Prev Frame |
+------------+---------+
sp+0x64 | | |
sp+0x60 | FPSCR | |
sp+0x5C | s15 | |
sp+0x58 | s14 | |
sp+0x54 | s13 | |
sp+0x50 | s12 | |
sp+0x4C | s11 | |
sp+0x48 | s10 | |
sp+0x44 | s9 | FP |
sp+0x40 | s8 | Frame |
sp+0x3C | s7 | |
sp+0x38 | s6 | |
sp+0x34 | s5 | |
sp+0x30 | s4 | |
sp+0x2C | s3 | |
sp+0x28 | s2 | |
sp+0x24 | s1 | |
sp+0x20 | s0 | |
------------------------
sp+0x1C | xpsr | |
sp+0x18 | pc | |
sp+0x14 | lr | |
sp+0x10 | r12 (ip) | Basic |
sp+0x0C | r3 | Frame |
sp+0x08 | r2 | |
sp+0x04 | r1 | |
sp+0x00 | r0 | |
------------------------
Volatile Register Stack Layout
Non-Volatile Stack Layout
The compiler can automatically handle non-volatile registers, so in the same context, restoring the environment does not require saving non-volatile registers. However, when the OS switches tasks, the non-volatile register environments of different tasks are different and need to be saved and restored.
XWOS’s non-volatile register stack layout on ARMv6/7-m platforms is as follows:
-----------------------------
| Volatile stack Frame |
+-----------------+---------+
sp+0x64 | s31 | |
sp+0x60 | s30 | |
sp+0x5C | s29 | |
sp+0x58 | s28 | |
sp+0x54 | s27 | |
sp+0x50 | s26 | |
sp+0x4C | s25 | FP |
sp+0x48 | s24 | Frame |
sp+0x44 | s23 | |
sp+0x40 | s22 | |
sp+0x3C | s21 | |
sp+0x38 | s20 | |
sp+0x34 | s19 | |
sp+0x30 | s18 | |
sp+0x2C | s17 | |
sp+0x28 | s16 | |
-----------------------------
sp+0x24 | lr (EXC_RETURN) | |
sp+0x20 | r11 (fp) | |
sp+0x1C | r10 (sl) | |
sp+0x18 | r9 | |
sp+0x14 | r8 | Basic |
sp+0x10 | r7 | Frame |
sp+0x0C | r6 | |
sp+0x08 | r5 | |
sp+0x04 | r4 | |
sp+0x00 | CONTROL | |
-----------------------------
Non-Volatile Register Stack Layout
Interrupts
The XWOS Porting Implementation Layer is located at:
xwcd/soc/arm/v6m/[CPU]/[SoC]/xwosimpl_irq.h
xwcd/soc/arm/v6m/[CPU]/[SoC]/xwosimpl_irq.c
xwcd/soc/arm/v7m/[CPU]/[SoC]/xwosimpl_irq.h
xwcd/soc/arm/v7m/[CPU]/[SoC]/xwosimpl_irq.c
Tick Timer
The XWOS Porting Implementation Layer is located at:
xwcd/soc/arm/v6m/[CPU]/[SoC]/xwosimpl_syshwt.h
xwcd/soc/arm/v6m/[CPU]/[SoC]/xwosimpl_syshwt.c
xwcd/soc/arm/v7m/[CPU]/[SoC]/xwosimpl_syshwt.h
xwcd/soc/arm/v7m/[CPU]/[SoC]/xwosimpl_syshwt.c