taskENTER_CRITICAL()
taskEXIT_CRITICAL()
[RTOS Kernel Control]
task. h
void taskENTER_CRITICAL( void );
void taskEXIT_CRITICAL( void );
Critical sections are entered by calling taskENTER_CRITICAL(), and subsequently
exited by calling taskEXIT_CRITICAL().
The taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros provide a basic critical
section implementation that works by simply disabling interrupts, either globally,
or up to a specific interrupt priority level. See the vTaskSuspendAll()
RTOS API function for information on creating a critical section without disabling
interrupts.
If the FreeRTOS port being used does not make use of the
configMAX_SYSCALL_INTERRUPT_PRIORITY
kernel configuration constant (also called
configMAX_API_CALL_INTERRUPT_PRIORITY), then calling taskENTER_CRITICAL() will
leave interrupts globally disabled. If the FreeRTOS port being used does make
use of the configMAX_SYSCALL_INTERRUPT_PRIORITY kernel configuration constant,
then calling taskENTER_CRITICAL() will leave interrupts at and below the interrupt
priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY disabled, and all higher
priority interrupt enabled.
Preemptive context switches only occur inside an interrupt, so will not occur
when interrupts are disabled. Therefore, the task that called
taskENTER_CRITICAL() is guaranteed to remain in the Running state until the
critical section is exited, unless the task explicitly attempts to block or
yield (which it should not do from inside a critical section).
Calls to taskENTER_CRITICAL() and taskEXIT_CRITICAL() are designed to nest.
Therefore, a critical section will only be exited when one call to
taskEXIT_CRITICAL() has been executed for every preceding call to
taskENTER_CRITICAL().
Critical sections must be kept very short, otherwise they will adversely affect
interrupt response times. Every call to taskENTER_CRITICAL() must be closely
paired with a call to taskEXIT_CRITICAL().
FreeRTOS API functions must not be called from within a critical section.
taskENTER_CRITICAL() and taskEXIT_CRITICAL()
must not be called from an interrupt service routine (ISR) - see
taskENTER_CRITICAL_FROM_ISR()
and taskEXIT_CRITICAL_FROM_ISR() for interrupt safe equivalents.
- Parameters:
-
-
Returns:
-
None
Example usage:
/* A function that makes use of a critical section. */
void vDemoFunction( void )
{
/* Enter the critical section. In this example, this function is itself called
from within a critical section, so entering this critical section will result
in a nesting depth of 2. */
taskENTER_CRITICAL();
/* Perform the action that is being protected by the critical section here. */
/* Exit the critical section. In this example, this function is itself called
from a critical section, so this call to taskEXIT_CRITICAL() will decrement the
nesting count by one, but not result in interrupts becoming enabled. */
taskEXIT_CRITICAL();
}
/* A task that calls vDemoFunction() from within a critical section. */
void vTask1( void * pvParameters )
{
for( ;; )
{
/* Perform some functionality here. */
/* Call taskENTER_CRITICAL() to create a critical section. */
taskENTER_CRITICAL();
/* Execute the code that requires the critical section here. */
/* Calls to taskENTER_CRITICAL() can be nested so it is safe to call a
function that includes its own calls to taskENTER_CRITICAL() and
taskEXIT_CRITICAL(). */
vDemoFunction();
/* The operation that required the critical section is complete so exit the
critical section. After this call to taskEXIT_CRITICAL(), the nesting depth
will be zero, so interrupts will have been re-enabled. */
taskEXIT_CRITICAL();
}
}
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.