Critical sections and Mutual Exclusion (Mutex)
The ZigBee 3.0 stack software provides features to prevent sections of application code from being preempted and/or re-entered. For example, when the application is writing data to memory, it may not be desirable for this operation to be interrupted and for an interrupt service routine to start writing to the same memory block.
Two features are provided to protect sections of application code:
Critical Section: A section of application code can be designated as a ‘critical section’, which means that the execution of this code section cannot be preempted by an interrupt with a priority level less than 12. A critical section should be short in order to avoid suspending interrupts for a long period of time.
Mutual Exclusion (Mutex): It may be desirable for a section of code not to be re-entrant. A ‘mutex’ can be associated with a code section to prevent it from being entered again before the current execution of the section has completed.
These features are described in more detail in the sub-sections below. The API resources to implement these features are detailed in Section 9.3.
Implementing a critical section
Interrupts with a priority level less than 12 cannot preempt the execution of a critical section of application code (though higher-priority interrupts can always preempt a critical section). This is illustrated in Figure 14 below, which shows the interplay between the main application thread and an interrupt service routine (ISR).
Priority of Main thread < Priority of Interrupt Service Routine (ISR) < 12
Critical Section Illustration
Critical section illustration
Time
A critical section of code must be delimited by the following two functions:
zps_eEnterCriticalSection() must be called at the start of the critical section.
zps_eExitCriticalSection() must be called at the end of the critical section.
A mutex can also be optionally associated with a critical section, to protect the section from re-entrancy. If required, the mutex can be specified in a parameter of zps_eEnterCriticalSection(). Mutexes are described in Section 5.9.3.2.
To implement critical sections, the application must maintain a ‘priority level’ value u8Level
(see Section 9.3.2.1) which contains the current priority level of the main application thread (when critical sections are not being executed). When a critical section is entered, the priority level of the main thread is increased such that interrupts with a priority of 11 or less cannot preempt the main thread. At the end of the critical section, the priority level of the main thread is returned to the value that was contained in u8Level
before the critical section was entered.
Parent topic:Implementing a critical section
Parent topic:Critical sections and Mutual Exclusion (Mutex)
Implementing a Mutex
A mutex can be associated with a section of application code to prevent the section from being re-entered before the current execution of the section has finished. The section of code to which the mutex will be applied must be delimited by the following two functions:
zps_u8GrabMutexLock() must be called at the start of the code section.
zps_u8ReleaseMutexLock() must be called at the end of the code section.
It is also possible to apply a mutex to a critical section, as described in Section 5.9.3.1.
When applying a mutex, a pointer must be provided to a user-defined mutex function with the following prototype:
((bool_t*) (*) (void))
This function must define and maintain a Boolean flag which indicates whether the corresponding mutex is active (TRUE) or inactive (FALSE). This flag is used by the API functions to determine whether the specified mutex is available. If this flag reads as FALSE at the start of the relevant code section, the mutex is applied and the above mutex function must set the flag to TRUE, but if the flag is already TRUE then the mutex cannot be applied (and the API function returns with a failure).
To implement mutex protection, the application must maintain a ‘priority level’ value u8Level
(see Section 9.3.2.1) which contains the current priority level of the main application thread (when mutex-protected sections are not being executed). When a mutex is applied, the priority level of the main thread is increased such that interrupts with a priority of 11 or less cannot preempt the main thread. When the mutex is released, the priority level of the main thread is returned to the value that was contained in u8Level
before the mutex was applied.
Parent topic:Critical sections and Mutual Exclusion (Mutex)
Parent topic:Using support software features