ARM Cortex-M processors support two main modes of operation to separate application-level code from system-level (privileged) operations. This is crucial for building safe and secure embedded systems.

1. Thread Mode

  • Default execution mode

  • Used by:

    • Application-level code

    • main() function and background tasks

  • Can run in either:

    • Privileged mode (full access)

    • Unprivileged mode (restricted access)

2. Handler Mode

  • Entered automatically when an exception or interrupt occurs

  • Always runs in Privileged mode

  • Used by:

    • Interrupt Service Routines (ISRs)

    • Fault handlers (e.g. HardFault, MemManage, etc.)

    • System-level operations (e.g. PendSV, SysTick)


Why Separate Modes?

Certain instructions like disabling interrupts, accessing system control registers, or performing privileged memory operations can compromise system stability or break critical services if misused.

By separating modes:

  • We protect the kernel/system from faulty or malicious application code

  • We enforce privilege levels, supporting a minimal security boundary even in bare-metal systems


Privilege Levels

Privilege LevelDescriptionAllowed Mode(s)
PrivilegedFull access to all instructions, system control space, and memory regionsThread & Handler
UnprivilegedLimited access. Cannot disable interrupts or access system controlThread only

Unprivileged code is typically application-level logic, while the kernel, ISRs, and system services run as privileged.


Mode Switching

  • The CPU starts in Thread Mode, running user code.

  • When an interrupt or exception occurs:

    • The core automatically switches to Handler Mode

    • Saves context to the stack

    • Executes the ISR or handler

  • Upon BX LR or return-from-exception:

    • The CPU restores context and switches back to Thread Mode

Register Banking

What is Register Banking?

Register banking is a technique where certain registers are swapped or replaced depending on the mode.
In Cortex-M, the only banked register is the Stack Pointer (SP).

RegisterBanked?Notes
R0–R12Shared across modes
R13 (SP)Separate for each stack mode
R14–R15LR (link register) and PC shared

The Two Stacks: MSP and PSP

ARM Cortex-M has two stack pointers, both pointing to separate stacks in memory:

Stack PointerNameUsed By
MSPMain Stack PointerHandler Mode + default Thread Mode
PSPProcess Stack PointerThread Mode (if configured)

Why Two Stacks?

  • To separate application tasks from system context.
  • Prevents corruption of ISR stack space by untrusted or buggy application code.
  • Allows an RTOS to:
    • Use PSP for tasks
    • Use MSP for system-level and interrupt handling This structure supports safe preemption, clean context switching, and modular RTOS design.