Hello! Welcome to the third module of our course.
In the last lesson, we concluded our deep dive into memory organization by examining endianness, a crucial concept for data representation and communication. We've built a solid understanding of how both peripherals and data are laid out in memory. Now, as promised, we shift our focus from the "what" (memory) to the "how" (processor behavior).
This lesson addresses the learning outcome: Describe the ARM exception model, including Reset, NMI, HardFault, and IRQs. This is the absolute foundation for writing any low-level driver that interacts with the real world, and a topic you can certainly expect to discuss in an interview for a driver development role. We'll explore how a Cortex-M processor suspends its normal execution to handle urgent events.
1. What is an Exception?
In the ARM world, an "exception" is the official term for any event that diverts the processor from its normal program flow. You'll often hear "interrupt" and "exception" used interchangeably, but it's more precise to think of an interrupt as one specific type of exception.
To understand the model, we first need to define some key terms.
A Practical guide to ARM Cortex-M Exception Handling
The article 'A Practical guide to ARM Cortex-M Exception Handling' provides excellent, clear definitions for the core concepts of the exception model.
Please read the section 'ARM Exception Model Overview'. Focus on understanding the three key identifiers for an exception: Exception Number, Priority Level, and its Synchronous/Asynchronous nature.
As you just read, every exception is identified by its Exception Number. This number is not just an ID; it's a direct index into a critical data structure called the Vector Table.
2. The Vector Table: The CPU's Roadmap
So how does the processor know what code to run when an exception occurs? It consults the vector table. This is simply a table of memory addresses, where each entry points to the start of a specific exception handler function (also called an Interrupt Service Routine, or ISR).
The vector table is fundamental to the entire boot-up and execution process. Let's explore how it works.
ARM - Cortex M: Exception model, Boot Flow and demo | Embedded Systems podcast, in Pyjama!
The video 'ARM - Cortex M: Exception model, Boot Flow and demo' gives a great walkthrough of the vector table's role, especially during the initial boot sequence.
Watch the segment from 01:52 to 14:20. The first part (until 08:29) explains what the vector table is and introduces the Vector Table Offset Register (VTOR), which is highly relevant to your background with bootloaders. The second part (from 09:03 to 14:20) details exactly how the CPU uses the first two entries of the vector table to boot up.
To summarize the key points from the video:
- Vector Table as a Map: It's an array where the index is the exception number and the value is the address of the handler function for that exception.
- VTOR: The
Vector Table Offset Registertells the CPU where the vector table is located in memory. This is what allows a bootloader and an application to have separate vector tables and manage interrupts independently. - Boot-up Sequence: On power-up, the Cortex-M core performs two crucial steps using the vector table:
- It reads the value at index 0 to initialize the Main Stack Pointer (MSP).
- It reads the value at index 1 (the Reset vector) to initialize the Program Counter (PC).
Execution then begins at the address pulled from the Reset vector. This very first handler to run is called the Reset Handler.

3. Types of Exceptions
ARM Cortex-M exceptions can be grouped into two main categories: internal system exceptions and external interrupts. The learning outcome for this lesson focuses on the most important ones.
System Exceptions (Exceptions 1-15)
These are built into the Cortex-M core architecture itself. The most critical ones are:
- Reset (Exception #1): As we just discussed, this isn't a typical exception you handle at runtime. Its vector points to the entry point of your entire program, which runs immediately after a chip reset.
- NMI - Non-Maskable Interrupt (Exception #2): This is the highest-priority exception after Reset. As its name implies, it cannot be ignored or "masked" by software. It's reserved for catastrophic system events, such as a watchdog timer signaling that the system has hung, or an error in another exception handler.
- HardFault (Exception #3): This is the default, catch-all fault handler. On simpler ARMv6-M cores (like Cortex-M0/M0+), all faults trigger the HardFault handler. On more advanced ARMv7-M cores (Cortex-M3/M4/M7), there are more specific fault handlers, but if they are disabled, their faults are "escalated" to a HardFault.
Given your experience, understanding the nuances of faults is critical for robust driver development and debugging.
How to Debug HardFaults on ARM Cortex-M MCUs
To go beyond just defining a HardFault, let's look at the different categories of faults that can occur. The video 'How to Debug HardFaults on ARM Cortex-M MCUs' provides a fantastic breakdown.
Watch the segment from 05:55 to 08:33. Pay close attention to the three main types of faults described: Usage Faults, Bus Faults, and MemManage (Memory Management) Faults, and the examples of what causes each one.
The key fault categories from the video are:
- Usage Fault: Illegal operations, such as executing an undefined instruction, an unaligned memory access, or dividing by zero.
- Bus Fault: Errors that occur during a memory access over the bus. This often happens when you try to read from or write to an invalid memory address that doesn't map to any physical memory or peripheral.
- MemManage Fault: Violations of memory protection rules defined in the Memory Protection Unit (MPU). You'll see this if you try to access a memory region that your current task is not permitted to. We will cover the MPU in a later module.
Understanding these specific fault types is invaluable for debugging. When a HardFault occurs, a set of Fault Status Registers can often tell you which type of fault it was, pointing you much closer to the root cause.
Test your understanding!
You are developing a new SPI driver. While testing, the system suddenly crashes into the HardFault_Handler. Your code involves calculating a buffer address using pointer arithmetic. Based on the fault types we just discussed, what is a likely cause of this crash?
Show answer
A Bus Fault is the most likely cause. An error in your pointer arithmetic could have resulted in an invalid address that points to a non-existent memory location. When the SPI driver code attempts to dereference this pointer to read or write data, the processor's bus interface will report an error, triggering the fault. This fault would then escalate to a HardFault if the BusFault handler isn't enabled.
External Interrupts (IRQs)
These are the exceptions generated by peripherals on the microcontroller—the timers, UARTs, ADCs, SPI controllers, and GPIO pins that allow the software to interact with the hardware world.
- Source: Originate from hardware outside the CPU core (e.g., a timer overflows, a byte is received by the UART).
- Path: The peripheral sends a signal to the Nested Vectored Interrupt Controller (NVIC). The NVIC is a crucial piece of hardware that manages all these external interrupts, prioritizing them and forwarding them to the core.
- Exception Numbers: These start from 16 and go up. The specific mapping (e.g., IRQ #5 is for Timer 2) is defined by the microcontroller vendor in the datasheet.

4. The Exception Handling Sequence
Now let's tie it all together. What exactly happens, step-by-step, when a peripheral triggers an interrupt?
ARM - Cortex M: Exception model, Boot Flow and demo | Embedded Systems podcast, in Pyjama!
The 'Exception model, Boot Flow and demo' video provides a clear, high-level walkthrough of the entire sequence, from the peripheral signal to the execution of the ISR.
Watch the segment from 29:17 to 39:02. This explains the entire process of context switching: how the processor saves its state on the stack, enters Handler Mode, executes the ISR, and then restores its state to resume normal operation.
The sequence is an automated, hardware-managed process:
- Assert Request: A peripheral asserts its interrupt request line to the NVIC.
- NVIC Detection: The NVIC checks if the interrupt is enabled and if its priority is higher than the currently executing code's priority.
- CPU Preemption: If the interrupt is accepted, the CPU stops its current execution.
- Context Saving (Stacking): The hardware automatically pushes a selection of core registers (R0-R3, R12, PC, LR, xPSR) onto the current stack. This "stack frame" preserves the state of the interrupted task. This is a key feature of Cortex-M, making interrupt handling fast and efficient.
- State Update: The CPU updates its internal state. It enters Handler Mode, and the Link Register (LR) is loaded with a special
EXC_RETURNvalue that tells the core how to return from the exception. - Vector Fetch: The CPU fetches the address of the correct ISR from the vector table (using the exception number provided by the NVIC).
- ISR Execution: The Program Counter is loaded with the ISR address, and the handler code begins to execute.
- Return and Context Restore (Unstacking): When the ISR finishes, it executes an instruction that branches to the
EXC_RETURNvalue in the LR. This signals the hardware to automatically pop the saved registers from the stack back into the core. The processor returns to its previous mode (e.g., Thread Mode) and resumes the interrupted task exactly where it left off.
This hardware-based context switching is what makes the Cortex-M architecture so well-suited for real-time applications.
Interview Preparation
Understanding this model is non-negotiable for a low-level role. Be ready to articulate these concepts clearly.
-
Question: "Can you explain the role of the vector table in a Cortex-M microcontroller? How is it used during boot-up?"
- Your Answer: "The vector table is a lookup table in memory that holds the starting addresses of all exception handlers. It's fundamental to the system. On boot, the processor hardware automatically reads the first entry to set the initial stack pointer and the second entry (the Reset vector) to get the address of the
Reset_Handler, which is the entry point of the entire application."
- Your Answer: "The vector table is a lookup table in memory that holds the starting addresses of all exception handlers. It's fundamental to the system. On boot, the processor hardware automatically reads the first entry to set the initial stack pointer and the second entry (the Reset vector) to get the address of the
-
Question: "What is the difference between a HardFault, an NMI, and a peripheral IRQ?"
- Your Answer: "They are all types of exceptions, but they differ in source and priority. A peripheral IRQ is an asynchronous request from hardware like a timer or UART, managed by the NVIC with configurable priority. An NMI is a non-maskable, high-priority interrupt for critical system errors like a watchdog timeout. A HardFault is a fault exception triggered by an illegal software operation, like accessing a bad memory address or executing an invalid instruction. It serves as the primary handler for severe programming errors."
-
Question: "Walk me through the high-level sequence of events when a UART receives a byte and triggers an interrupt."
- Your Answer: "First, the UART peripheral asserts its interrupt line to the NVIC. The NVIC checks if the UART interrupt is enabled and has sufficient priority to preempt the current task. If so, the CPU hardware automatically saves the core register context onto the stack. It then fetches the address of the UART's ISR from the vector table, loads it into the program counter, and begins executing the handler. Once the handler finishes, the hardware automatically restores the saved context from the stack, and the original program flow resumes seamlessly."
Conclusion
In this lesson, we have unpacked the core principles of the ARM exception model. This is the mechanism that enables an embedded system to be responsive and event-driven.
Key Takeaways:
- An exception is any event that changes the normal flow of control.
- The vector table is a map of exception numbers to handler function addresses, and it's essential for booting the system.
- System exceptions like Reset, NMI, and HardFault are built into the core for handling startup and critical errors.
- IRQs are external interrupts from peripherals, managed by the NVIC.
- The Cortex-M hardware performs an automatic context save and restore process, making exception handling fast and deterministic.
Next Lesson Preview:
We've seen that the NVIC plays a central role in managing all the peripheral interrupts. In our next lesson, we will focus exclusively on it. We will explore the architecture of the NVIC and learn how to configure it, specifically focusing on setting interrupt priorities to manage preemption and ensure that the most critical tasks are always serviced first.