ARM Cortex-M4 Architecture

The Cortex-M4 processor is a low-power processor that features low gate count, low interrupt latency, and low-cost debug.

Cortex-M4 is the workhorse of the mid-range microcontroller world: STM32F4, nRF52, Kinetis K, MAX32, SAM4 — all the same core, different peripherals. This post is a tour of the core itself: what's inside, how memory is laid out, and how it handles exceptions.

Key features at a glance

Block diagram

The diagram below — from the ARM Cortex-M4 Technical Reference Manual — shows the major blocks and how they connect.

ARM Cortex-M4 block diagram

The standard memory map

One of the strengths of Cortex-M is its fixed memory map. Every chip from every vendor uses the same regions for the same purposes — that's why CMSIS code is portable.

Address rangePurpose
0x0000_0000 – 0x1FFF_FFFFCode (Flash) — vector table lives at the bottom
0x2000_0000 – 0x3FFF_FFFFSRAM — bit-band region in the lowest 1 MB
0x4000_0000 – 0x5FFF_FFFFPeripheral — vendor SoC peripherals (USART, SPI, GPIO…)
0x6000_0000 – 0x9FFF_FFFFExternal RAM (FSMC, QSPI, etc.)
0xA000_0000 – 0xDFFF_FFFFExternal devices
0xE000_0000 – 0xE00F_FFFFPrivate Peripheral Bus — NVIC, SCB, SysTick, MPU, debug

Operating modes & privilege

Cortex-M has two execution modes and two privilege levels:

Stack pointers — MSP and PSP

Two banked stack pointers:

The CONTROL register's SPSEL bit picks which one is active in thread mode.

Exception model

Cortex-M defines 15 fixed system exceptions plus up to 240 external IRQs. Numbers 1–15 are exceptions; 16+ are device-specific IRQs.

#Exception
1Reset
2NMI — non-maskable
3HardFault — catch-all when other faults are masked
4MemManage — MPU violation
5BusFault — invalid memory access
6UsageFault — undefined instruction, unaligned access
11SVCall — supervisor call (used by RTOSes)
14PendSV — deferred context switch (used by RTOSes)
15SysTick

The System Control Block (SCB)

The SCB groups registers that govern processor-wide behaviour: reset, sleep modes, interrupt vector base address, and configurable fault handling. The most-used registers:

Enabling the FPU (Cortex-M4F only)

The FPU starts disabled out of reset. You must enable access to coprocessors CP10 and CP11 in CPACR, ideally inside SystemInit() before any C code runs that might issue a VFP instruction.

// Grant full access to CP10 & CP11 (FPU)
SCB->CPACR |= (0xF << 20);
__DSB();
__ISB();

Forget this and any FPU instruction — generated as soon as you compile with -mfpu=fpv4-sp-d16 -mfloat-abi=hard — will cause a UsageFault at the first float operation. Classic "works on M3, crashes on M4" bug.

Reference manuals

Originally published on the WordPress mirror. — First version at thedarknightcom.wordpress.com.
← Back to all posts