Merge branch 'bugfix/doc_freertos_smp_macros' into 'master'

docs: Update SMP descriptions for taskENTER_CRITICAL/taskEXIT_CRITICAL

Closes IDFGH-4428

See merge request espressif/esp-idf!12219
This commit is contained in:
Angus Gratton
2021-02-05 08:14:50 +08:00
2 changed files with 28 additions and 27 deletions

View File

@@ -134,7 +134,7 @@ do not disable the interrupts (because they already are).
This all assumes that interrupts are either entirely disabled or enabled. Interrupt priority levels This all assumes that interrupts are either entirely disabled or enabled. Interrupt priority levels
will break this scheme. will break this scheme.
Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vTaskEnterCritical, meaning Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vPortEnterCritical, meaning
that either function can be called both from ISR as well as task context. This is not standard FreeRTOS that either function can be called both from ISR as well as task context. This is not standard FreeRTOS
behaviour; please keep this in mind if you need any compatibility with other FreeRTOS implementations. behaviour; please keep this in mind if you need any compatibility with other FreeRTOS implementations.
*/ */

View File

@@ -223,7 +223,7 @@ In vanilla FreeRTOS, suspending the scheduler via :cpp:func:`vTaskSuspendAll` wi
prevent calls of ``vTaskSwitchContext`` from context switching until the prevent calls of ``vTaskSwitchContext`` from context switching until the
scheduler has been resumed with :cpp:func:`xTaskResumeAll`. However servicing ISRs scheduler has been resumed with :cpp:func:`xTaskResumeAll`. However servicing ISRs
are still permitted. Therefore any changes in task states as a result from the are still permitted. Therefore any changes in task states as a result from the
current running task or ISRSs will not be executed until the scheduler is current running task or ISRs will not be executed until the scheduler is
resumed. Scheduler suspension in vanilla FreeRTOS is a common protection method resumed. Scheduler suspension in vanilla FreeRTOS is a common protection method
against simultaneous access of data shared between tasks, whilst still allowing against simultaneous access of data shared between tasks, whilst still allowing
ISRs to be serviced. ISRs to be serviced.
@@ -279,15 +279,14 @@ to unblock multiple tasks at the same time.
Critical Sections & Disabling Interrupts Critical Sections & Disabling Interrupts
---------------------------------------- ----------------------------------------
Vanilla FreeRTOS implements critical sections in ``vTaskEnterCritical`` which Vanilla FreeRTOS implements critical sections with ``taskENTER_CRITICAL()`` which
disables the scheduler and calls ``portDISABLE_INTERRUPTS``. This prevents calls ``portDISABLE_INTERRUPTS()``. This prevents preemptive context switches and
context switches and servicing of ISRs during a critical section. Therefore, servicing of ISRs during a critical section. Therefore, critical sections are
critical sections are used as a valid protection method against simultaneous used as a valid protection method against simultaneous access in vanilla FreeRTOS.
access in vanilla FreeRTOS.
.. only:: not CONFIG_FREERTOS_UNICORE .. only:: not CONFIG_FREERTOS_UNICORE
On the other hand, the ESP32 has no hardware method for cores to disable each On the other hand, {IDF_TARGET_NAME} has no hardware method for cores to disable each
others interrupts. Calling ``portDISABLE_INTERRUPTS()`` will have no effect on others interrupts. Calling ``portDISABLE_INTERRUPTS()`` will have no effect on
the interrupts of the other core. Therefore, disabling interrupts is **NOT** the interrupts of the other core. Therefore, disabling interrupts is **NOT**
a valid protection method against simultaneous access to shared data as it a valid protection method against simultaneous access to shared data as it
@@ -299,42 +298,44 @@ access in vanilla FreeRTOS.
ESP-IDF contains some modifications to work with dual core concurrency, ESP-IDF contains some modifications to work with dual core concurrency,
and the dual core API is used even on a single core only chip. and the dual core API is used even on a single core only chip.
For this reason, ESP-IDF FreeRTOS implements critical sections using special mutexes, For this reason, ESP-IDF FreeRTOS implements critical sections using special
referred by portMUX_Type objects on top of specific spinlock component mutexes, referred by ``portMUX_Type`` objects. These are implemented on top of a
and calls to enter or exit a critical must provide a spinlock object that specific spinlock component. Calls to ``taskENTER_CRITICAL`` or
is associated with a shared resource requiring access protection. ``taskEXIT_CRITICAL`` each provide a spinlock object as an argument. The
When entering a critical section in ESP-IDF FreeRTOS, the calling core will disable spinlock is associated with a shared resource requiring access protection. When
its scheduler and interrupts similar to the vanilla FreeRTOS implementation. However, entering a critical section in ESP-IDF FreeRTOS, the calling core will disable
the calling core will also take the locks whilst the other core is left unaffected during interrupts similar to the vanilla FreeRTOS implementation, and will then take the
the critical section. If the other core attempts to take the spinlock, it spinlock and enter the critical section. The other core is unaffected at this point,
will spin until the lock is released. Therefore, the ESP-IDF FreeRTOS unless it enters its own critical section and attempts to take the same spinlock.
implementation of critical sections allows a core to have protected access to a In that case it will spin until the lock is released. Therefore, the ESP-IDF FreeRTOS
shared resource without disabling the other core. The other core will only be implementation of critical sections allows a core to have protected access to a shared
affected if it tries to concurrently access the same resource. resource without disabling the other core. The other core will only be affected if it
tries to concurrently access the same resource.
The ESP-IDF FreeRTOS critical section functions have been modified as follows… The ESP-IDF FreeRTOS critical section functions have been modified as follows…
- ``taskENTER_CRITICAL(mux)``, ``taskENTER_CRITICAL_ISR(mux)``, - ``taskENTER_CRITICAL(mux)``, ``taskENTER_CRITICAL_ISR(mux)``,
``portENTER_CRITICAL(mux)``, ``portENTER_CRITICAL_ISR(mux)`` are all macro ``portENTER_CRITICAL(mux)``, ``portENTER_CRITICAL_ISR(mux)`` are all macro
defined to call :cpp:func:`vTaskEnterCritical` defined to call internal function :cpp:func:`vPortEnterCritical`
- ``taskEXIT_CRITICAL(mux)``, ``taskEXIT_CRITICAL_ISR(mux)``, - ``taskEXIT_CRITICAL(mux)``, ``taskEXIT_CRITICAL_ISR(mux)``,
``portEXIT_CRITICAL(mux)``, ``portEXIT_CRITICAL_ISR(mux)`` are all macro ``portEXIT_CRITICAL(mux)``, ``portEXIT_CRITICAL_ISR(mux)`` are all macro
defined to call :cpp:func:`vTaskExitCritical` defined to call internal function :cpp:func:`vPortExitCritical`
- ``portENTER_CRITICAL_SAFE(mux)``, ``portEXIT_CRITICAL_SAFE(mux)`` macro identifies - ``portENTER_CRITICAL_SAFE(mux)``, ``portEXIT_CRITICAL_SAFE(mux)`` macro identifies
the context of execution, i.e ISR or Non-ISR, and calls appropriate critical the context of execution, i.e ISR or Non-ISR, and calls appropriate critical
section functions (``port*_CRITICAL`` in Non-ISR and ``port*_CRITICAL_ISR`` in ISR) section functions (``port*_CRITICAL`` in Non-ISR and ``port*_CRITICAL_ISR`` in ISR)
in order to be in compliance with Vanilla FreeRTOS. in order to be in compliance with Vanilla FreeRTOS.
For more details see :component_file:`esp_hw_support/include/soc/spinlock.h` For more details see :component_file:`esp_hw_support/include/soc/spinlock.h`,
:component_file:`freertos/include/freertos/task.h`,
and :component_file:`freertos/tasks.c` and :component_file:`freertos/tasks.c`
It should be noted that when modifying vanilla FreeRTOS code to be ESP-IDF It should be noted that when modifying vanilla FreeRTOS code to be ESP-IDF
FreeRTOS compatible, it is trivial to modify the type of critical section FreeRTOS compatible, it is trivial to modify the type of critical section called
called as they are all defined to call the same function. As long as the same as they are all defined to call the same function. As long as the same spinlock
spinlock is provided upon entering and exiting, the type of call should not is provided upon entering and exiting, the exact macro or function used for the
matter. call should not matter.
.. only:: not CONFIG_FREERTOS_UNICORE .. only:: not CONFIG_FREERTOS_UNICORE