How does interrupt nesting work on Cortex-M? What are the stack implications?
Interrupt nesting occurs automatically on Cortex-M whenever a higher preemption priority interrupt fires while a lower-priority ISR is executing. The hardware pushes another stack frame (8 registers = 32 bytes on Cortex-M3/M4, or 26 words = 104 bytes on Cortex-M4F with FPU context if floating-point was used) onto the current stack and begins executing the higher-priority ISR. This can happen recursively: a priority-0 interrupt can preempt a priority-1 ISR that already preempted a priority-2 ISR, creating three nested stack frames on top of whatever the main application was using.
The stack implications are significant and often underestimated. Each nesting level consumes at least 32 bytes for the hardware-saved frame, plus whatever stack the ISR itself uses for local variables and function calls. On Cortex-M4F with lazy FPU stacking, if any ISR in the chain uses floating-point, an additional 72 bytes are reserved (18 FPU registers times 4 bytes) even if the FPU was not actually used in every frame — the hardware reserves space pessimistically during lazy stacking and fills it only if needed. With 4-5 nesting levels, the worst-case stack consumption from interrupts alone can exceed 500 bytes. If the system uses the MSP for both handler and thread mode (the default without an RTOS), this must be added to the application's own stack usage.
A practical approach to stack sizing: calculate the worst-case nesting depth (determined by how many distinct preemption priority levels you actually use), multiply by the per-level stack cost (frame size + ISR local usage), add the application's own worst-case stack depth, and then add a safety margin of 20-25%. Tools like the Keil stack analyzer or manual call-tree analysis help determine per-ISR stack usage. A common mistake is ignoring ISR stack contributions entirely and then seeing stack overflow corruption that manifests as random crashes under heavy interrupt load — a bug that is extremely difficult to reproduce and diagnose without a stack watermark or MPU guard region.
Source: Interrupts & Priorities Q&A
