HomeARM CourseDay 20
DAY 20 · SYSTEM & MEMORY

The MPU — Memory Protection

By EcrioniX · Updated Jun 6, 2026

A single stray pointer can corrupt memory and crash a system in ways that are agony to debug. The Memory Protection Unit stops that at the hardware level: it polices who may touch which memory and how, turning a silent corruption into an instant, catchable fault. It's the foundation of safe and secure embedded software.

1. The problem: nothing stops a bad access

By default, any code can write anywhere — over a constant table, into a peripheral, off the end of the stack, even through a null pointer at address 0. The bug doesn't crash where it happens; it corrupts something and the system fails mysteriously later. The MPU's job is to make illegal accesses fail immediately and visibly.

2. What the MPU does: regions + permissions

The MPU divides the address space into a small number of regions (typically 8 or 16). For each region you define a base address, a size, and a set of rules:

AttributeControls
Access permissionno-access / read-only / read-write, and whether unprivileged code may access it
Execute-never (XN)whether instructions may be fetched from the region (data regions → XN)
Memory typenormal vs device/strongly-ordered (controls caching & reordering)
Shareability/cachecache & coherency behaviour for the region

Classic safe setup: flash = read-only + executable, RAM = read-write + execute-never, peripherals = read-write + device + XN. Now a wild jump into data, or a write into code, is impossible.

3. The fault: caught, not corrupted

If software violates a region's rules, the MPU blocks the access and raises a MemManage fault, vectoring to a fault handler (an exception, per Day 17). The handler reads fault-status registers to learn what and where:

void MemManage_Handler(void) { uint32_t cfsr = SCB->CFSR; // what kind of fault uint32_t addr = SCB->MMFAR; // faulting address (if valid) // log it, kill the offending task, or reset — don't run on corrupted state }

💡 A smoke detector for memory

Without an MPU, a memory bug is a slow gas leak — you only notice when something explodes far away. The MPU is a smoke detector wired to each room: the instant something's wrong, it goes off at the source, so you know exactly which line and which address.

4. MPU vs MMU — don't confuse them

MPUMMU
Address translationnone — uses physical addressesvirtual → physical (page tables)
Granularitya few fixed regionsfine-grained pages (e.g. 4 KB)
Per-process address spacenoyes
Typical coreCortex-M / Cortex-RCortex-A
Runsbare-metal / RTOSLinux, rich OSes

An MPU only protects; an MMU also translates, giving every process its own virtual view of memory. That's a later lesson in the course — the MPU is the lightweight, deterministic cousin built for real-time systems.

5. Why it matters: isolation

✅ The mental model

The MPU is a hardware access policy over a handful of memory regions: each gets read/write/execute permissions and attributes, and any violation becomes an instant MemManage fault instead of silent corruption. Unlike an MMU, it does no translation — it just protects — which makes it perfect for real-time isolation, privilege separation and safety.

🎯 Day 20 takeaways

Quick check

  1. What three things do you define for each MPU region?
  2. Name the one capability an MMU has that an MPU does not.
  3. How would you use the MPU to catch a stack overflow?

FAQ

What is an MPU?

A hardware block that enforces access permissions and attributes on a few memory regions, faulting on any disallowed access.

MPU vs MMU?

An MPU only protects fixed physical regions; an MMU also translates virtual→physical addresses with page tables for per-process spaces.

Why use one?

Safety, security and reliability — task isolation, privilege separation, and catching stray accesses as faults.

Previous
← Day 19: Memory map & buses

← Back to the full course roadmap