CortexM3 Exceptions and Interrupts
Cortex-M3 (Architecture version V7M) is fundamentally different in its exception processing from other ARM architecture implementations. In fact this is probably the single biggest area of difference between architecture version V7-M and other versions of the ARM architecture.
As well as sophisticated exception priority concepts in the core architecture, the Cortex-M3 includes an integrated Nested Vectored Interrupt Controller (the NVIC). The Cortex-M3 also incorporates a basic system timer that is typically used as the ‘heartbeat’ interrupt for an OS or RTOS. The SYSTICK and NVIC together provide enough underlying system resources in the core to enable a generic RTOS port to the core rather than relying on anything on a particular device.
Cortex M3 versus other ARMs
The ARM architecture traditionally has a very simple exception processing architecture consisting of two external interrupt inputs (IRQ and FIQ) each with an architecturally fixed priority. One of the criticisms of this model for microcontrollers was that it was over simplistic and in particular there was no concept of an ‘unmaskable’ interrupt – often called NMI on other microprocessor architectures. In addition, external logic had to be added to ensure that lower priority interrupts (like IRQ) were serviced if they were currently being masked by a higher priority interrupt (like FIQ), otherwise the core would just proceed as if the exception had never occurred.
Cortex-M3 supports up to 255 different exceptions, 15 of which are reserved for system (core) exceptions and anything above and including number 16 (a total of 240) are available for external interrupt inputs. How many of these external interrupts are implemented is dependant on the implementation of the device (chip) incorporating the Cortex-M3 core. In general a smaller exception number has a higher priority – hence the system (core) interrupts are the low numbers. However, most of the exceptions have a programmable priority.
Fixed priority interrupts:
- RESET : Priority = -3 (the highest)
- NMI : Priority = -2
- HARD FAULT: Priority = -1
This is significantly different from other ARM architecture processors. On other ARM implementations, the vector table is literally where the processor jumps to in the event of an exception. So, for example, at RESET, the processor just starts to execute instructions at location zero. Each vector location has space for two 32-bit ARM instructions but execution will just continue unless one of those instructions causes a branch to somewhere else in memory.
Cortex-M3 is the first Thumb-2 only implementation and does not therefore enter the 32-bit ARM mode on an exception. This necessarily implies that the exception model is going to be different from other ARM cores. The vector table in Cortex-M3 really is a vector table (more similar to other processor architectures), so for example location zero contains an initial value of the program counter and location 4 (the second 32-bit word) contains an initial value for the stack pointer.
Registers Controlling Exceptions
BASEPRI (Base Priority) Register
This register can be used to mask exceptions that have a priority equal to or lower than the value in this register.
During debugging of code, it is useful to look at the contents of BASEPRI to see what exceptions are being masked at various points in a programs flow.
PRIMASK (Priority Mask) Register
This is a single bit register that is used to mask all exceptions except NMI and Hard Fault.
This is a single bit register that is used to mask all exceptions except NMI. ie. It masks HARD FAULT.