Core facts apply to every ARMv7-M part (Cortex-M3, M4, M7) unless marked. Device facts are for the STM32F407 used throughout the course. Always confirm device details against the reference manual (RM0090) for your exact part.
Register Name Role Saved by r0-r3a1-a4 Arguments, return value (r0, r0:r1 for 64-bit), scratch Caller; hardware on exception entry r4-r11v1-v8 Local variables preserved across calls Callee; RTOS context switch in software r12ipIntra-procedure scratch (linker veneers) Caller; hardware on exception entry r13spStack pointer, banked as MSP or PSP; must be 8-byte aligned at public interfaces r14lrReturn address after bl; EXC_RETURN value inside a handler Hardware on exception entry r15pcProgram counter; bit 0 of branch targets selects Thumb (must be 1) Hardware on exception entry s0-s31 / d0-d15FPU Single-precision registers (M4F); s0-s15 caller-saved, s16-s31 callee-saved Hardware stacks s0-s15, FPSCR (lazily) FPSCRFPU status and control: flags, rounding mode
Accessed with MRS and MSR only (CMSIS: __get_X / __set_X).
Register Bits Meaning APSR31 N, 30 Z, 29 C, 28 V, 27 Q, 19:16 GE (M4/M7) Condition flags from the last flag-setting instruction IPSR8:0 Exception number of the running handler, 0 in Thread mode EPSR24 T, 26:25 and 15:10 ICI/IT Thumb state (always 1), interrupted multi-cycle or IT-block state xPSRAPSR, IPSR, EPSR combined; bit 9 in the stacked copy flags 4-byte stack paddingPRIMASK0 1 = mask all configurable-priority exceptions (everything except NMI and HardFault) FAULTMASK0 1 = also mask HardFault (only NMI runs); cleared automatically on exception return BASEPRI7:0 (top 4 bits used on STM32) Mask exceptions with priority value greater than or equal to this; 0 disables masking BASEPRI_MAXWrite alias that only raises the mask, never lowers it CONTROL0 nPRIV, 1 SPSEL, 2 FPCA Unprivileged Thread mode; use PSP in Thread mode; FP context active MSPMain stack pointer: used by handlers and, by default, Thread mode PSPProcess stack pointer: used by RTOS tasks MSPLIM, PSPLIMStack limit registers, ARMv8-M (M23/M33) only
Mode Entered by Stack Privilege Thread Reset, exception return to Thread MSP or PSP (CONTROL.SPSEL)Privileged or unprivileged (CONTROL.nPRIV) Handler Any exception Always MSP Always privileged
Exc # Exception Vector offset Priority Notes (0) Initial MSP value 0x000Loaded into sp at reset 1 Reset 0x004-3 (fixed) Loaded into pc at reset 2 NMI 0x008-2 (fixed) Clock security system on STM32 3 HardFault 0x00C-1 (fixed) All faults escalate here if their handler is disabled or cannot run 4 MemManage 0x010configurable MPU violation, execute from XN region 5 BusFault 0x014configurable Bus error on fetch or data access 6 UsageFault 0x018configurable Undefined instruction, invalid state, divide by zero (if trapped) 7-10 reserved (SecureFault is 7 on ARMv8-M) 0x01C-0x02811 SVCall 0x02Cconfigurable svc instruction12 DebugMonitor 0x030configurable Software debug monitor 13 reserved 0x03414 PendSV 0x038configurable Software-pended, used for RTOS context switches 15 SysTick 0x03Cconfigurable Core timer 16 + n IRQn 0x040 + 4nconfigurable Device interrupts; STM32F407 has 82 (IRQ0 to IRQ81)
IRQn Name Vector offset 0 WWDG0x0404 FLASH0x0505 RCC0x0546 EXTI00x0587-10 EXTI1 to EXTI40x05C-0x06811-17 DMA1_Stream0 to DMA1_Stream60x06C-0x08418 ADC (ADC1, ADC2, ADC3)0x08823 EXTI9_50x09C28 TIM20x0B029 TIM30x0B430 TIM40x0B831 I2C1_EV0x0BC32 I2C1_ER0x0C035 SPI10x0CC37 USART10x0D438 USART20x0D840 EXTI15_100x0E041 RTC_Alarm0x0E447 DMA1_Stream70x0FC54 TIM6_DAC0x11855 TIM70x11C56-60 DMA2_Stream0 to DMA2_Stream40x120-0x13067 OTG_FS0x14C68-70 DMA2_Stream5 to DMA2_Stream70x150-0x15871 USART60x15C81 FPU0x184
Pushed automatically by hardware on exception entry, onto the stack in use (MSP or PSP). The frame is 8-byte aligned; if padding was needed, bit 9 of the stacked xPSR is set.
Basic frame (8 words, 32 bytes) Extended frame with FPU (26 words, 104 bytes)
sp+0x00 r0 sp+0x00 .. sp+0x1C same 8 words as basic
sp+0x10 r12 sp+0x60 FPSCR
sp+0x14 lr (of interrupted code) sp+0x64 reserved (alignment)
sp+0x18 pc (return address)
With lazy stacking (FPCCR.LSPEN = 1, the default), space for s0-s15 and FPSCR is reserved but the values are only written if the handler executes an FPU instruction.
Inside a handler, lr holds one of these. Branching to it (bx lr, pop {pc}) performs the exception return.
Value Return to Stack Frame 0xFFFFFFF1Handler mode MSPbasic 0xFFFFFFF9Thread mode MSPbasic 0xFFFFFFFDThread mode PSPbasic 0xFFFFFFE1Handler mode MSPextended (FPU) 0xFFFFFFE9Thread mode MSPextended (FPU) 0xFFFFFFEDThread mode PSPextended (FPU)
Bit 2 = 1 means the frame is on PSP; bit 3 = 1 means return to Thread mode; bit 4 = 0 means an extended FPU frame was stacked. A fault handler tests bit 2 to find the stacked frame.
Base 0xE000E100. Each 32-bit register covers 32 IRQs: IRQ n is bit n % 32 of register n / 32.
Register Address Access Purpose ISER0-ISER70xE000E100-0xE000E11Cwrite 1 to set Enable interrupt ICER0-ICER70xE000E180-0xE000E19Cwrite 1 to clear Disable interrupt ISPR0-ISPR70xE000E200-0xE000E21Cwrite 1 to set Set pending ICPR0-ICPR70xE000E280-0xE000E29Cwrite 1 to clear Clear pending IABR0-IABR70xE000E300-0xE000E31Cread-only Active IPR0-IPR590xE000E400-0xE000E4EFbyte accessible One priority byte per IRQ at 0xE000E400 + n STIR0xE000EF00write-only Write IRQ number to trigger it from software
On the STM32F407 only the top 4 bits of each priority byte are implemented: priority 5 is written as 0x50. Lower value means higher priority. USART2 (IRQ 38) is enabled by writing 1u << 6 to ISER1.
Base 0xE000ED00.
Register Address Key bits ACTLR0xE000E0080 DISMCYCINT, 1 DISDEFWBUF (makes bus faults precise), 2 DISFOLD CPUID0xE000ED00Implementer 0x41 (Arm), PartNo 0xC24 for Cortex-M4 ICSR0xE000ED0431 NMIPENDSET, 28 PENDSVSET, 27 PENDSVCLR, 26 PENDSTSET, 25 PENDSTCLR, 20:12 VECTPENDING, 8:0 VECTACTIVE VTOR0xE000ED08Vector table address (aligned to the table size rounded up to a power of two, at least 128 bytes; 512 bytes for STM32F407) AIRCR0xE000ED0C31:16 VECTKEY (write 0x05FA), 15 ENDIANNESS, 10:8 PRIGROUP, 2 SYSRESETREQ, 1 VECTCLRACTIVE SCR0xE000ED101 SLEEPONEXIT, 2 SLEEPDEEP, 4 SEVONPEND CCR0xE000ED143 UNALIGN_TRP, 4 DIV_0_TRP, 8 BFHFNMIGN, 9 STKALIGN SHPR10xE000ED18Priority bytes: 7:0 MemManage, 15:8 BusFault, 23:16 UsageFault SHPR20xE000ED1C31:24 SVCall SHPR30xE000ED2023:16 PendSV, 31:24 SysTick SHCSR0xE000ED2416 MEMFAULTENA, 17 BUSFAULTENA, 18 USGFAULTENA, plus active and pending bits CFSR0xE000ED28MMFSR 7:0, BFSR 15:8, UFSR 31:16 (see fault bits below) HFSR0xE000ED2C1 VECTTBL, 30 FORCED (escalated from another fault), 31 DEBUGEVT DFSR0xE000ED30Debug fault status MMFAR0xE000ED34Faulting address for MemManage (valid if MMARVALID) BFAR0xE000ED38Faulting address for BusFault (valid if BFARVALID) AFSR0xE000ED3CAuxiliary, implementation-defined CPACR0xE000ED8823:20 CP10 and CP11 access; write 0xF << 20 for full FPU access
AIRCR.PRIGROUP splits the priority byte into preempt priority and subpriority. With 4 implemented bits: PRIGROUP 3 (or less) gives 16 preempt levels and no subpriority; PRIGROUP 4 gives 8 and 2; 5 gives 4 and 4; 6 gives 2 and 8; 7 gives 1 and 16.
Software reset: write (0x05FAu << 16) | (1u << 2) to AIRCR, preserving PRIGROUP, then DSB.
Register Address Key bits SYST_CSR (CTRL)0xE000E0100 ENABLE, 1 TICKINT, 2 CLKSOURCE (1 = processor clock, 0 = external reference, HCLK/8 on STM32), 16 COUNTFLAG (clears on read) SYST_RVR (LOAD)0xE000E01423:0 reload value; period = LOAD + 1 cycles SYST_CVR (VAL)0xE000E01823:0 current value; any write clears it to 0 SYST_CALIB0xE000E01CCalibration value (vendor-defined)
1 ms tick at 16 MHz: LOAD = 16000 - 1. At 168 MHz: LOAD = 168000 - 1. Maximum LOAD is 0x00FFFFFF (about 99.9 ms at 168 MHz).
Register Address Key bits DHCSR0xE000EDF00 C_DEBUGEN (debugger attached), 1 C_HALT; write key 0xA05F in 31:16 DEMCR0xE000EDFC24 TRCENA (enable DWT and ITM), 0 VC_CORERESET DWT_CTRL0xE00010000 CYCCNTENA; 31:28 NUMCOMP (number of comparators, 4 on M4) DWT_CYCCNT0xE000100432-bit cycle counter DWT_COMPn0xE0001020 + 0x10 * nWatchpoint comparator address DWT_MASKn0xE0001024 + 0x10 * nAddress mask (ignore low bits) DWT_FUNCTIONn0xE0001028 + 0x10 * nComparator function (read, write, access watchpoint) DWT_LAR0xE0001FB0Lock access; write 0xC5ACCE55 to unlock (needed on Cortex-M7) ITM_STIMn0xE0000000 + 4 * nStimulus ports for SWO output FPCCR0xE000EF3431 ASPEN (automatic FP state preservation), 30 LSPEN (lazy stacking) FPCAR0xE000EF38Address of reserved FP frame space DBGMCU_CR0xE0042004STM32: keep debug alive in Sleep/Stop/Standby (bits 0 to 2) DBGMCU_APB1_FZ0xE0042008STM32: freeze timers, watchdogs, I2C timeouts while the core is halted
Cycle counter enable:
#define DEMCR ( * ( volatile uint32_t * ) 0x E000EDFC u )
#define DWT_CTRL ( * ( volatile uint32_t * ) 0x E0001000 u )
#define DWT_CYCCNT ( * ( volatile uint32_t * ) 0x E0001004 u )
static inline void cyccnt_init ( void )
DEMCR |= ( 1 u << 24 ); /* TRCENA */
DWT_CTRL |= 1 u ; /* CYCCNTENA */
Register Address Purpose MPU_TYPE0xE000ED9015:8 DREGION: number of regions (8 on STM32F407) MPU_CTRL0xE000ED940 ENABLE, 1 HFNMIENA, 2 PRIVDEFENA MPU_RNR0xE000ED98Region number selector MPU_RBAR0xE000ED9CRegion base address, 4 VALID, 3:0 REGION MPU_RASR0xE000EDA028 XN, 26:24 AP, 21:16 TEX/S/C/B, 15:8 SRD (subregion disable), 5:1 SIZE (region = 2^(SIZE+1) bytes), 0 ENABLE
Bit Name Register Typical cause 0 IACCVIOL MMFSR Executing from an XN region or MPU-forbidden address, often a bad function pointer 1 DACCVIOL MMFSR Data access forbidden by the MPU; address in MMFAR 3 MUNSTKERR MMFSR MPU fault while unstacking on exception return (corrupted stack pointer) 4 MSTKERR MMFSR MPU fault while stacking on exception entry (stack overflow into guard region) 5 MLSPERR MMFSR MPU fault during lazy FP state preservation 7 MMARVALID MMFSR MMFAR holds the faulting address8 IBUSERR BFSR Bus error on instruction fetch: jumped to unmapped memory 9 PRECISERR BFSR Precise data bus error; address in BFAR: bad pointer, unclocked peripheral on some parts 10 IMPRECISERR BFSR Buffered write failed later; pc is not the culprit. Set ACTLR.DISDEFWBUF to make it precise 11 UNSTKERR BFSR Bus error unstacking on exception return 12 STKERR BFSR Bus error stacking on entry: sp points outside RAM, stack overflow 13 LSPERR BFSR Bus error during lazy FP stacking 15 BFARVALID BFSR BFAR holds the faulting address16 UNDEFINSTR UFSR Undefined instruction: executing data, corrupted code, wrong -mcpu 17 INVSTATE UFSR Branch to an address with bit 0 clear (Thumb bit missing), bad function pointer 18 INVPC UFSR Bad EXC_RETURN value in lr on exception return 19 NOCP UFSR FPU instruction with FPU disabled: CPACR not set before using float 24 UNALIGNED UFSR Unaligned access with CCR.UNALIGN_TRP set, or unaligned ldm/stm/ldrd 25 DIVBYZERO UFSR Integer divide by zero with CCR.DIV_0_TRP set
The fault bits are write-1-to-clear. HFSR.FORCED means a configurable fault escalated; look in CFSR for the original cause.
Instruction CMSIS Guarantees Use it dmb__DMB()Memory accesses before it are observed before accesses after it Sharing buffers with DMA or another core; implementing locks dsb__DSB()All memory accesses complete before the next instruction executes Before wfi; after clearing an interrupt flag at the end of an ISR; after AIRCR reset request; after writing VTOR or MPU regions isb__ISB()Flushes the pipeline so later instructions are fetched fresh After writing CONTROL, CPACR (enable FPU), VTOR, MPU enable; after self-modifying code compiler barrier __asm volatile("" ::: "memory")Compiler does not move memory accesses across it; emits nothing Ordering around critical sections; not a hardware barrier
Canonical sequences: VTOR write then DSB then ISB; CPACR write then DSB then ISB; DSB then WFI.
Intrinsic Effect __enable_irq() / __disable_irq()cpsie i / cpsid i (clear or set PRIMASK)__get_PRIMASK() / __set_PRIMASK(x)Read or write PRIMASK (save/restore critical sections) __get_BASEPRI() / __set_BASEPRI(x)Read or write BASEPRI (value already shifted, 0x50 for priority 5) __enable_fault_irq() / __disable_fault_irq()Clear or set FAULTMASK __get_MSP() / __set_MSP(x)Main stack pointer __get_PSP() / __set_PSP(x)Process stack pointer __get_CONTROL() / __set_CONTROL(x)CONTROL register (follow with __ISB())__get_IPSR(), __get_xPSR()Current exception number, full status __DSB(), __DMB(), __ISB()Barriers __WFI(), __WFE(), __SEV()Wait for interrupt, wait for event, send event __NOP()One nop __BKPT(n)Breakpoint instruction (halts if a debugger is attached, otherwise HardFault) __REV(x), __REV16(x), __REVSH(x)Byte reverse 32-bit, each halfword, signed halfword __RBIT(x)Reverse bit order __CLZ(x)Count leading zeros __LDREXW(p), __STREXW(v, p), __CLREX()Exclusive load/store for lock-free atomics (__STREXW returns 0 on success) __SSAT(x, n), __USAT(x, n)Signed and unsigned saturate to n bits NVIC_EnableIRQ(n) / NVIC_DisableIRQ(n)Write ISER / ICER NVIC_SetPriority(n, p)Set priority; p is unshifted (0 to 15 on STM32); also works for negative system exception numbers NVIC_SetPendingIRQ(n) / NVIC_ClearPendingIRQ(n)Write ISPR / ICPR NVIC_GetPendingIRQ(n), NVIC_GetActive(n)Read pending, active NVIC_SetPriorityGrouping(g)Write AIRCR.PRIGROUP with the key NVIC_SystemReset()Request a system reset via AIRCR.SYSRESETREQ SysTick_Config(ticks)Load SysTick, set its priority to the lowest, enable with interrupt; returns 1 if ticks too large
Core Architecture FPU MPU Cache DSP/SIMD Bit-banding TrustZone Priority bits (typical) M0 ARMv6-M no no no no no no 2 M0+ ARMv6-M no optional no no no no 2 M3 ARMv7-M no optional no no optional no 3 to 8 M4 ARMv7E-M optional SP optional no yes optional no 3 to 8 (4 on STM32) M7 ARMv7E-M optional SP or DP optional optional I and D yes no no 3 to 8 M23 ARMv8-M Baseline no optional no no no optional 2 M33 ARMv8-M Mainline optional SP optional no optional no optional 3 to 8
Region Address Size Flash (main memory) 0x08000000-0x080FFFFF1 MB, sectors 0-3 16 KB, 4 64 KB, 5-11 128 KB Boot alias 0x00000000Flash, system memory, or SRAM depending on BOOT pins CCM RAM 0x10000000-0x1000FFFF64 KB, CPU data bus only, no DMA, no code execution System memory (ROM bootloader) 0x1FFF000030 KB OTP area 0x1FFF7800528 bytes Unique device ID 0x1FFF7A1096 bits Flash size register 0x1FFF7A2216 bits, size in KB Option bytes 0x1FFFC000SRAM1 0x20000000-0x2001BFFF112 KB SRAM2 0x2001C000-0x2001FFFF16 KB Backup SRAM 0x400240004 KB (battery-backed domain) Bit-band alias (SRAM) 0x22000000alias = 0x22000000 + (offset * 32) + (bit * 4) Bit-band alias (peripherals) 0x42000000alias = 0x42000000 + (offset * 32) + (bit * 4) Private peripheral bus 0xE0000000-0xE00FFFFFNVIC, SCB, SysTick, DWT, ITM, MPU
Bus Peripheral Base APB1 TIM2 0x40000000APB1 TIM3 0x40000400APB1 TIM4 0x40000800APB1 TIM5 0x40000C00APB1 TIM6 0x40001000APB1 TIM7 0x40001400APB1 RTC and backup registers 0x40002800APB1 WWDG 0x40002C00APB1 IWDG 0x40003000APB1 SPI2 / I2S2 0x40003800APB1 SPI3 / I2S3 0x40003C00APB1 USART2 0x40004400APB1 USART3 0x40004800APB1 UART4 0x40004C00APB1 UART5 0x40005000APB1 I2C1 0x40005400APB1 I2C2 0x40005800APB1 I2C3 0x40005C00APB1 CAN1 0x40006400APB1 CAN2 0x40006800APB1 PWR 0x40007000APB1 DAC 0x40007400APB2 TIM1 0x40010000APB2 TIM8 0x40010400APB2 USART1 0x40011000APB2 USART6 0x40011400APB2 ADC1 / ADC2 / ADC3 0x40012000 / 0x40012100 / 0x40012200, common 0x40012300APB2 SDIO 0x40012C00APB2 SPI1 0x40013000APB2 SYSCFG 0x40013800APB2 EXTI 0x40013C00APB2 TIM9 / TIM10 / TIM11 0x40014000 / 0x40014400 / 0x40014800AHB1 GPIOA to GPIOI 0x40020000 + 0x400 * n (A 0x40020000, D 0x40020C00, E 0x40021000, I 0x40022000)AHB1 CRC 0x40023000AHB1 RCC 0x40023800AHB1 Flash interface 0x40023C00AHB1 DMA1 0x40026000AHB1 DMA2 0x40026400AHB1 Ethernet MAC 0x40028000AHB1 USB OTG HS 0x40040000AHB2 USB OTG FS 0x50000000AHB2 RNG 0x50060800
RCC base 0x40023800.
Register Offset Key bits CR0x000 HSION, 1 HSIRDY, 16 HSEON, 17 HSERDY, 18 HSEBYP, 19 CSSON, 24 PLLON, 25 PLLRDY PLLCFGR0x045:0 PLLM, 14:6 PLLN, 17:16 PLLP, 22 PLLSRC (1 = HSE), 27:24 PLLQ CFGR0x081:0 SW, 3:2 SWS (0 HSI, 1 HSE, 2 PLL), 7:4 HPRE, 12:10 PPRE1, 15:13 PPRE2 AHB1RSTR0x10Reset bits, same positions as AHB1ENR APB1RSTR0x20Reset bits, same positions as APB1ENR APB2RSTR0x24Reset bits, same positions as APB2ENR AHB1ENR0x30Clock enables (below) AHB2ENR0x34Clock enables (below) APB1ENR0x40Clock enables (below) APB2ENR0x44Clock enables (below) BDCR0x70Backup domain: LSE, RTC clock source CSR0x740 LSION, 1 LSIRDY, 24 RMVF, 25 BORRSTF, 26 PINRSTF, 27 PORRSTF, 28 SFTRSTF, 29 IWDGRSTF, 30 WWDGRSTF, 31 LPWRRSTF
Register Bit Peripheral AHB1ENR0 to 8 GPIOA to GPIOI (GPIOD is bit 3, GPIOE bit 4) AHB1ENR12 CRC AHB1ENR18 Backup SRAM AHB1ENR20 CCM data RAM AHB1ENR21 DMA1 AHB1ENR22 DMA2 AHB2ENR6 RNG AHB2ENR7 USB OTG FS APB1ENR0 TIM2 APB1ENR1 TIM3 APB1ENR2 TIM4 APB1ENR3 TIM5 APB1ENR4 TIM6 APB1ENR5 TIM7 APB1ENR11 WWDG APB1ENR14 SPI2 APB1ENR15 SPI3 APB1ENR17 USART2 APB1ENR18 USART3 APB1ENR21 I2C1 APB1ENR22 I2C2 APB1ENR23 I2C3 APB1ENR25 CAN1 APB1ENR28 PWR APB1ENR29 DAC APB2ENR0 TIM1 APB2ENR4 USART1 APB2ENR5 USART6 APB2ENR8 ADC1 APB2ENR12 SPI1 APB2ENR14 SYSCFG APB2ENR16 TIM9
The IWDG has no enable bit: it runs from the LSI and starts when you write 0xCCCC to IWDG_KR.
Clock Maximum (STM32F407) SYSCLK, HCLK (AHB) 168 MHz PCLK2 (APB2) 84 MHz PCLK1 (APB1) 42 MHz Timer clocks 2 x PCLK when the APB prescaler is not 1 (84 MHz on APB1 timers at full speed) ADC clock 36 MHz Flash wait states at 168 MHz, 2.7 to 3.6 V 5