Interrupt prioritization

From SEGGER Wiki
Revision as of 10:34, 26 August 2019 by Martin (talk | contribs)
Jump to: navigation, search

Most CPUs support interrupts with different priorities. Utilizing these, developers may determine the order of execution when two or more interrupts occur simultaneously. The number of available interrupt priority levels depends on the CPU and/or the implemented interrupt controller.

With embOS, different levels of interrupts are grouped into one of two categories, i.e. high priority and low priority interrupts:

  • High priority interrupts are called zero-latency interrupts within the embOS documentation.
  • Low priority interrupts are called embOS interrupts within the embOS documentation.

Generally, the differences between embOS interrupts and zero-latency interrupts are as follows:

embOS interrupts Zero-latency interrupts
May call any embOS API function that is legal for ISRs Must not call any embOS API function
Must call OS_INT_Enter() or OS_INT_EnterNestable() as first embOS API function in the ISR Must not call OS_INT_Enter() or OS_INT_EnterNestable()
Must call OS_INT_Leave() or OS_INT_LeaveNestable() as last embOS API function in the ISR Must not call OS_INT_Leave() or OS_INT_LeaveNestable()
Can temporarily be disabled by embOS and thus may be affected by additional latency Are never disabled by embOS and thus are not affected by additional latency
Typically include the lower half of all available priorities Typcially include the upper half of all available priorities

This means that zero latency interrupts can interrupt the operating system at any time, even in critical sections such as the modification of RTOS-maintained linked lists.

Interrupt priority levels with ARMv7-M

With its architectural specification, ARMv7-M supports up to 256 interrupt priorities, i.e. the values 0 to 255 (where 0 indicates the highest and 255 the lowest possible priority). The threshold between embOS interrupts and zero-latency interrupts by default is configured at 128 (where 0 to 127 are considered zero-latency, while 128 to 255 are considered embOS interrupts). Since at reset all priorities are initialized with 0, users need to explicitly configure the priority of interrupts that should be used as embOS interrupts.

Most ARMv7-M devices, however, implement fewer supported levels, for example 8, 16, or 32 priority levels only. In those cases, the threshold between embOS interrupts and zero-latency interrupts is at 4, 8, or 16, respectively. These values may be used as-is when using CMSIS API functions like NVIC_SetPriority(), for these functions take the number of implemented interrupt levels for the actual device into consideration. embOS API functions on the other hand, e.g. OS_ARM_ISRSetPrio(), are agnostic of the actual number of implemented priorities and thus require the use of the numbers 0 to 255 in all cases. Since the least significant bits of the written priority value are ignored by devices that do not implement all priority levels, this gives the exact same results, but still needs to be considered when using the embOS API function.