The Cortex-M4 processor from ARM has support for up to 256 different priority levels for interrupts and exception handling. This allows for very flexible and customizable prioritization of different events and exceptions in the system. Having many priority levels allows software developers to carefully organize and structure their interrupt service routines (ISRs) based on the relative importance and time-sensitivity of different external events, peripheral actions, and internal exceptions.
Overview of Priority Levels
In the Cortex-M4, the split between exceptions and interrupts is configurable. Up to 240 priority levels can be assigned to external interrupts from peripherals. The remaining priority levels are then available for exceptions such as resets, faults, and software interrupts.
The full 256 priority levels are numbered 0 to 255, with 0 being the highest priority. So the lower the number, the higher the priority. The exception model for the Cortex-M4 processor allows flexibility in assigning exception types to any of the available priority levels.
There are some rules and conventions usually followed when mapping exceptions and interrupts to priority levels:
- Reset is always the highest priority at level 0
- Memory management faults are generally high priority
- Usage faults and bus faults are usually slightly lower priority than memory faults
- Supervisor calls to the kernel are mid-priority
- Software interrupts for task switching may be above peripheral interrupts
- Most peripheral interrupts are clustered in priority levels 32 to 239
- Low power management events are often the lowest priority exceptions
But the user has the ability to customize the priority mapping based on their specific application requirements. The only fixed priority levels are for Reset (level 0) and Non-Maskable Interrupt (NMI) at level 1.
Configuring Priority Levels
There are a number of registers involved in the configuration and control of priority levels on the Cortex-M4. These include:
- The Application Interrupt and Reset Control Register (AIRCR)
- The System Handler Control and State Register (SHCSR)
- The System Handler Priority Registers (SHPR1-3)
- The NVIC ISERx and ICERx Interrupt Set/Clear Enable Registers
- The NVIC IPxR Interrupt Priority Registers
The AIRCR provides overall configuration capabilities such as:
- Setting the total number of priority bits supported (8 bits allows 256 priority levels)
- Splitting priority levels between exceptions and interrupts
- Setting the priority grouping within priority bits
The SHCSR and SHPR registers are used to set priorities for the various system exception handlers like memory management, bus fault, and supervisor call.
The NVIC registers (Nested Vectored Interrupt Controller) are used to enable/disable interrupts and set their priorities. The ISERx registers enable external interrupts from peripherals. The IPxR registers contain the 8-bit priority field for each interrupt.
An important configuration setting that affects priority levels is the priority grouping field in the AIRCR register. This controls how the 8-bit priority field in the IPxR registers is split between preemption priority bits and subpriority bits.
The possible groupings are:
- Grouping 0: 8 bits for preemption priority, 0 bits for subpriority
- Grouping 1: 7 bits for preemption priority, 1 bit for subpriority
- Grouping 2: 6 bits for preemption priority, 2 bits for subpriority
- Grouping 3: 5 bits for preemption priority, 3 bits for subpriority
- Grouping 4: 4 bits for preemption priority, 4 bits for subpriority (the default grouping)
The preemption priority determines the strict hierarchy between interrupts. Higher priority interrupts always preempt lower priority ones. The subpriority helps determine priority between multiple pending interrupts of the same preemption priority level.
Optimizing Priority Levels
Choosing the right priority configuration for an application requires careful analysis of use cases and timing requirements. Some tips include:
- Critical and time-sensitive interrupts should be highest priority
- High-frequency interrupts should generally be lower priority
- Assign similar priority levels to related peripheral interrupts
- Use priority grouping to create logical preemption levels
- Distribute interrupts across priority levels to maximize concurrency
- Mind the priority inversion problem with shared resources
Striking the right balance between urgency, frequency, and workload across priority levels allows developers to fully utilize the Cortex-M4’s priority scheme for responsive and robust system behavior. Prefer using many small priority-specific ISRs instead of fewer monolithic ISRs.
Testing and profiling the system under different priority configurations is important. Monitoring and recording the actual priority levels of different runtime events helps validate priority assignments.
Priority Level Use Cases
Some example use cases that benefit from extensively utilizing the Cortex-M4’s priority levels include:
- Real-time control systems – For closed loop motor control or industrial automation, the highest priority levels are used for the most latency-sensitive sensor measurements and actuator updates.
- Automotive applications – Important safety alerts like airbag deployment or anti-lock brake events require low latency preemption at higher priority than entertainment functions.
- IoT endpoints – For smart home devices or fitness trackers, user interface events preempt lower priority Bluetooth LE activities. Motion sensor data preempts other lower frequency sensor acquisition.
- Audio/video products – For speakers or cameras, the audio or video data streams are high priority. Lower priority levels handle command and control, debugging info, and background error monitoring.
For these complex, responsive systems the Cortex-M4’s breadth of priority options enables detailed control over event latency, responsiveness, concurrence, and reliability.
Comparisons to other ARM cores
Compared to other ARM cores, the Cortex-M4 has one of the most flexible and configurable priority schemes:
- The Cortex-M0+ only has 32 priority levels which is much more limiting.
- The Cortex-R5 has 128 priority levels for interrupts.
- The Cortex-A5 has only 16 priority levels which requires very coarse groupings.
This highlights the Cortex-M4’s strength for complex embedded applications requiring fine-grained, real-time responsiveness and throughput.
In summary, the Cortex-M4 processor enables very sophisticated interrupt and exception prioritization across 256 priority levels, with flexible grouping options. This allows for highly customized mapping of interrupts to match application requirements and real-time responsiveness needs. Sensitivity analysis, testing under load, and runtime profiling help developers validate and tune the priority schemes. Overall the wide range of prioritization capabilities makes the Cortex-M4 well suited for demanding embedded applications in automation, control systems, IoT, consumer devices, and other domains requiring complex real-time behavior.