Quality RTOS & Embedded Software

  Real time embedded FreeRTOS RSS feed  

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:
None
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.