freertos: port*_CRITICAL_SAFE API added

port*_CRITICAL_SAFE API calls port*_CRITICAL or port*_CRITICAL_ISR
depending on the context (Non-ISR or ISR respectively).

FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE Kconfig option added

Signed-off-by: Sachin Parekh <sachin.parekh@espressif.com>
This commit is contained in:
Sachin Parekh 2019-03-25 15:55:57 +05:30 committed by bot
parent b3f4755ac2
commit 4b739249c2
3 changed files with 65 additions and 0 deletions

View file

@ -419,4 +419,18 @@ menu "FreeRTOS"
abort the application. This option is also required for GDB backtraces and C++
exceptions to work correctly inside top-level task functions.
config FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER
bool "Check that mutex semaphore is given by owner task"
default y
help
If enabled, assert that when a mutex semaphore is given, the task giving the
semaphore is the task which is currently holding the mutex.
config FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
bool "Tests compliance with Vanilla FreeRTOS port*_CRITICAL calls"
default n
help
If enabled, context of port*_CRITICAL calls (ISR or Non-ISR) would be checked to be in compliance with Vanilla FreeRTOS.
e.g Calling port*_CRITICAL from ISR context would cause assert failure
endmenu

View file

@ -209,8 +209,23 @@ void vPortCPUReleaseMutex(portMUX_TYPE *mux, const char *function, int line);
void vTaskEnterCritical( portMUX_TYPE *mux, const char *function, int line );
void vTaskExitCritical( portMUX_TYPE *mux, const char *function, int line );
#ifdef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
/* Calling port*_CRITICAL from ISR context would cause an assert failure.
* If the parent function is called from both ISR and Non-ISR context then call port*_CRITICAL_SAFE
**/
#define portENTER_CRITICAL(mux) do { \
configASSERT(!xPortInIsrContext()); \
vTaskEnterCritical(mux, __FUNCTION__, __LINE__); \
} while(0)
#define portEXIT_CRITICAL(mux) do { \
configASSERT(!xPortInIsrContext()); \
vTaskExitCritical(mux, __FUNCTION__, __LINE__); \
} while(0)
#else
#define portENTER_CRITICAL(mux) vTaskEnterCritical(mux, __FUNCTION__, __LINE__)
#define portEXIT_CRITICAL(mux) vTaskExitCritical(mux, __FUNCTION__, __LINE__)
#endif
#define portENTER_CRITICAL_ISR(mux) vTaskEnterCritical(mux, __FUNCTION__, __LINE__)
#define portEXIT_CRITICAL_ISR(mux) vTaskExitCritical(mux, __FUNCTION__, __LINE__)
#else
@ -229,12 +244,43 @@ void vPortCPUAcquireMutex(portMUX_TYPE *mux);
bool vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout_cycles);
void vPortCPUReleaseMutex(portMUX_TYPE *mux);
#ifdef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
/* Calling port*_CRITICAL from ISR context would cause an assert failure.
* If the parent function is called from both ISR and Non-ISR context then call port*_CRITICAL_SAFE
**/
#define portENTER_CRITICAL(mux) do { \
configASSERT(!xPortInIsrContext()); \
vTaskEnterCritical(mux); \
} while(0)
#define portEXIT_CRITICAL(mux) do { \
configASSERT(!xPortInIsrContext()); \
vTaskExitCritical(mux); \
} while(0)
#else
#define portENTER_CRITICAL(mux) vTaskEnterCritical(mux)
#define portEXIT_CRITICAL(mux) vTaskExitCritical(mux)
#endif
#define portENTER_CRITICAL_ISR(mux) vTaskEnterCritical(mux)
#define portEXIT_CRITICAL_ISR(mux) vTaskExitCritical(mux)
#endif
#define portENTER_CRITICAL_SAFE(mux) do { \
if (xPortInIsrContext()) { \
portENTER_CRITICAL_ISR(mux); \
} else { \
portENTER_CRITICAL(mux); \
} \
} while(0)
#define portEXIT_CRITICAL_SAFE(mux) do { \
if (xPortInIsrContext()) { \
portEXIT_CRITICAL_ISR(mux); \
} else { \
portEXIT_CRITICAL(mux); \
} \
} while(0)
// Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any?
// These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level.
//

View file

@ -377,6 +377,11 @@ The ESP-IDF FreeRTOS critical section functions have been modified as follows…
``portEXIT_CRITICAL(mux)``, ``portEXIT_CRITICAL_ISR(mux)`` are all macro
defined to call :cpp:func:`vTaskExitCritical`
- ``portENTER_CRITICAL_SAFE(mux)``, ``portEXIT_CRITICAL_SAFE(mux)`` macro identifies
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)
in order to be in compliance with Vanilla FreeRTOS.
For more details see :component_file:`freertos/include/freertos/portmacro.h`
and :component_file:`freertos/task.c`