5.5.1 · D5Embedded Systems & Real-Time Software
Question bank — Microcontroller architecture — ARM Cortex-M series (M0, M3, M4, M7)
Before we start, three words this page leans on, in plain language:
True or false — justify
An M4 has an FPU, therefore double (64-bit) math on it runs in hardware.
False. The M4 FPU is single-precision (32-bit) only, so every
double silently falls back to slow software emulation — see IEEE-754 floating point for why 64-bit is a different format entirely.A 6-stage pipeline (M7) always finishes any given program in fewer cycles than a 2-stage pipeline (M0).
False. Deeper pipes buy higher clock speed, not free IPC; on branchy code the bigger misprediction and fill penalties can make the deep pipe waste more cycles per branch. See Pipelining and superscalar execution.
On an ideal (no-stall) pipeline, average cycles-per-instruction approaches 1 no matter how many stages.
True. The extra fill cycles are paid once; as instruction count grows they average away, so IPC → 1 for any fixed .
Superscalar (dual-issue) means the M7 always executes two instructions every cycle.
False. It issues up to two; only pairs with no dependency and the right resources co-issue, so real IPC is roughly with –, not 2.
"Vectored" interrupts mean the CPU runs a software loop to find the correct handler faster.
False. Vectored means each interrupt has its own table slot, so the hardware jumps straight to the handler with no dispatch loop at all — see Interrupts and the NVIC.
Automatic register stacking on the NVIC lets a plain C function be the interrupt handler.
True. The hardware pushes R0–R3, R12, LR, PC, xPSR itself, so you don't need an assembly stub to save state, which also removes a source of latency jitter.
Adding a cache to the M7 makes its execution timing more deterministic.
False. A hit is fast but a miss is slow, so runtime becomes data-dependent — worse for worst-case analysis; that is why real-time code often lives in TCM instead.
Memory-mapped I/O means GPIO needs special "in/out" CPU instructions.
False. It means the opposite: peripherals live at ordinary addresses, so normal load/store instructions reach them — see Memory-mapped I/O and GPIO.
Determinism requires interrupt latency to be zero.
False. Determinism requires latency to be bounded and knowable (); each term is nonzero but computable.
The MPU (Memory Protection Unit) is the same thing as a cache.
False. The Memory Protection Unit (MPU) checks permissions on address ranges (can this code write here?); a cache is a speed copy of memory. Different jobs entirely.
Spot the error
"We enabled -mfloat-abi=hard in the compiler, so the FPU is definitely on at runtime."
Error: compiler flags only generate FP instructions; you must also set the CP10/CP11 bits in the CPACR register at startup, or the first FP instruction traps as a HardFault.
"To go faster on our FIR filter we picked an M3 at 120 MHz over an M4 at 100 MHz."
Error: the M4 does a multiply-accumulate in one instruction (
MLA, or two-at-once via SIMD SMLAD), so it wins per cycle on DSP; the M3's clock edge rarely closes a 2–4× per-MHz gap. See Fixed-point vs floating-point DSP."Our RTOS runs every task on the MSP so the kernel and tasks share one stack."
Error: tasks should run on the PSP (Process Stack Pointer) while handlers use MSP, so a task overrunning its stack can't corrupt the kernel — see RTOS task scheduling and context switching.
"A 1000-iteration loop of 10 instructions costs cycles because each pass fills the 3-stage pipe."
Error: the pipe fills once, not per pass; cost is cycles because instructions stream continuously across iterations.
"On M4F we used sin() and double for our PID because floats lose precision."
Error:
sin() and double route through software emulation on M4F; you throw away the hardware FPU. Use sinf() and float literals like 3.14f to actually hit silicon."We removed the pipeline entirely so timing is perfectly deterministic."
Error: a pipeline doesn't destroy determinism — its fill/stall costs are knowable. The real determinism killers are unbounded features like cache misses, not overlap of fetch/decode/execute.
Why questions
Why does ARM sell a family (M0/M3/M4/M7) instead of one universal core?
Because embedded needs range from a $0.20 pin-toggler (wants cheapest/lowest-power M0) to a camera FFT pipeline (wants cached high-clock M7); no single design is optimal across power, area, and throughput at once.
Why does the M7 add a 6th pipeline stage if IPC still tends toward 1?
Shorter logic per stage lets the chip clock higher (more MHz), so total work-per-second rises even though per-cycle throughput doesn't — depth buys clock, not IPC.
Why are there two stack pointers (MSP and PSP)?
To isolate faults: each RTOS task gets its own PSP stack while interrupts run on the shared MSP, so one task's stack overflow can't overwrite kernel or handler state.
Why is "automatic 8-register stacking in a fixed cycle count" a big deal for real-time?
Because a fixed, knowable stacking cost makes worst-case interrupt latency computable, which is exactly the determinism real-time deadlines depend on.
Why can a shallow 2-stage M0+ be more deterministic than an M7 on tiny interrupt code?
Short branchy handlers suffer from the M7's deep-pipe fill and branch-misprediction penalties; the M0+ has almost no such penalty, giving tighter, more predictable timing.
Why does SIMD (SMLAD) roughly halve FIR filter cycles versus a plain MLA?
SIMD packs two 16-bit multiply-accumulates into one 32-bit instruction, so one instruction does the work of two — see Fixed-point vs floating-point DSP.
Edge cases
What happens if you execute a floating-point instruction on M4F before enabling CP10/CP11?
The CPU has no permission for the coprocessor, so the instruction traps as a HardFault instead of computing — a classic "FPU present but disabled" boot bug.
What happens to timing when a critical loop's data no longer fits in the M7 cache?
You start taking cache misses, so per-access time balloons and becomes data-dependent; the fix is placing that hot code/data in TCM for guaranteed single-cycle access.
Degenerate case: a program with exactly one instruction on an -stage pipeline costs how many cycles, and why isn't it 1?
It costs cycles, because the single instruction must still travel through all stages to complete — the "1 per cycle" figure only holds after the pipe is already full.
Limiting case: as the fraction of co-issuable pairs on the M7, what does its IPC become?
IPC ; with no pairs able to co-issue, dual-issue gives no benefit and the core behaves like a single-issue machine. See Pipelining and superscalar execution.
Edge case: a lower-priority interrupt fires while a higher-priority handler is running — does it run immediately?
No; it waits (the term), but the NVIC still records it and runs it right after, and a higher-priority IRQ would instead preempt via nesting — see Interrupts and the NVIC.
Edge case: you set an MPU region as read-only, then your code writes to it. What occurs?
The Memory Protection Unit (MPU) rejects the write and raises a fault, catching the bug at the moment of the illegal access rather than letting silent corruption spread.
Boundary: is a cache hit deterministic in latency?
A hit is fast and roughly fixed, but you cannot guarantee every access is a hit, so the access as a whole stays non-deterministic — worst-case must assume the miss.
Recall Quick self-test
The M4 FPU handles which precision in hardware? ::: Single-precision (32-bit) only; double falls back to software.
Deeper pipeline primarily buys you what? ::: Higher clock speed, not higher IPC.
Determinism means latency is what? ::: Bounded and knowable — not zero.