diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h index f5a4057296..ae34151994 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h @@ -85,6 +85,13 @@ typedef spinlock_t portMUX_TYPE; /**< Spi BaseType_t xPortCheckIfInISR(void); +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortCheckIfInISR() internally + */ +void vPortAssertIfInISR(void); + // ------------------ Critical Sections -------------------- /* @@ -148,6 +155,15 @@ void vPortCleanUpTCB ( void *pxTCB ); #define portENABLE_INTERRUPTS() vPortClearInterruptMask(1) #define portRESTORE_INTERRUPTS(x) vPortClearInterruptMask(x) +/** + * @brief Assert if in ISR context + * + * TODO: Enable once ISR safe version of vTaskEnter/ExitCritical() is implemented + * for single-core SMP FreeRTOS Kernel. (IDF-10540) + */ +// #define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + + // ------------------ Critical Sections -------------------- #define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index b4483209f0..4d248aa08b 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -279,6 +279,12 @@ BaseType_t xPortCheckIfInISR(void) return uxInterruptNesting; } +void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortCheckIfInISR() == 0); +} + // ------------------ Critical Sections -------------------- void IRAM_ATTR vPortTakeLock( portMUX_TYPE *lock ) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h index 6121f981cb..ab381603b1 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h @@ -95,6 +95,13 @@ typedef spinlock_t portMUX_TYPE; /**< Spi BaseType_t xPortCheckIfInISR(void); +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortCheckIfInISR() internally + */ +void vPortAssertIfInISR(void); + // ------------------ Critical Sections -------------------- UBaseType_t uxPortEnterCriticalFromISR( void ); @@ -151,6 +158,14 @@ void vPortCleanUpTCB ( void *pxTCB ); XTOS_SET_INTLEVEL(0); \ }) +/** + * @brief Assert if in ISR context + * + * TODO: Enable once ISR safe version of vTaskEnter/ExitCritical() is implemented + * for single-core SMP FreeRTOS Kernel. (IDF-10540) + */ +// #define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + /* Note: XTOS_RESTORE_INTLEVEL() will overwrite entire PS register on XEA2. So we need ot make the value INTLEVEL field ourselves */ diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index e6d24fcac9..c91e57c5cb 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -313,6 +313,12 @@ BaseType_t xPortCheckIfInISR(void) return ret; } +void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortCheckIfInISR() == 0); +} + // ------------------ Critical Sections -------------------- void vPortTakeLock( portMUX_TYPE *lock ) diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h index d719560520..51b3619aec 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h @@ -132,6 +132,13 @@ typedef uint32_t TickType_t; */ BaseType_t xPortInIsrContext(void); +/** + * @brief Assert if in ISR context + * + * - Asserts on xPortInIsrContext() internally + */ +void vPortAssertIfInISR(void); + /** * @brief Check if in ISR context from High priority ISRs * @@ -323,6 +330,11 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void) #define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMask() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) vPortClearInterruptMask(uxSavedStatusValue) +/** + * @brief Assert if in ISR context + */ +#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() + // ------------------ Critical Sections -------------------- #define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();} diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index d4206ccaa3..c588a8962b 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -229,6 +229,12 @@ BaseType_t xPortInIsrContext(void) return uxInterruptNesting; } +void vPortAssertIfInISR(void) +{ + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortInIsrContext() == 0); +} + BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void) { /* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */ diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h index 28538f1cf5..b47e50b2fd 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h @@ -165,12 +165,9 @@ typedef uint32_t TickType_t; BaseType_t xPortInIsrContext(void); /** - * @brief Asserts if in ISR context + * @brief Assert if in ISR context * * - Asserts on xPortInIsrContext() internally - * - * @note [refactor-todo] Check if this API is still required - * @note [refactor-todo] Check if this should be inlined */ void vPortAssertIfInISR(void); @@ -444,6 +441,9 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void); #define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMaskFromISR() #define portCLEAR_INTERRUPT_MASK_FROM_ISR(prev_level) vPortClearInterruptMaskFromISR(prev_level) +/** + * @brief Assert if in ISR context + */ #define portASSERT_IF_IN_ISR() vPortAssertIfInISR() // ------------------ Critical Sections -------------------- diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index d382ec4c20..7fab30cbd4 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -282,7 +282,8 @@ BaseType_t xPortInIsrContext(void) void vPortAssertIfInISR(void) { - configASSERT(xPortInIsrContext()); + /* Assert if the interrupt nesting count is > 0 */ + configASSERT(xPortInIsrContext() == 0); } BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void) diff --git a/components/freertos/test/port/test_freertos_isinisrcontext.c b/components/freertos/test/port/test_freertos_isinisrcontext.c index e1be84ef7f..6e916d37fd 100644 --- a/components/freertos/test/port/test_freertos_isinisrcontext.c +++ b/components/freertos/test/port/test_freertos_isinisrcontext.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -62,3 +62,20 @@ TEST_CASE("xPortInIsrContext test", "[freertos]") #endif + +#if !CONFIG_FREERTOS_SMP // TODO: Enable when IDF-10540 is fixed + +static void testint_assert(void) +{ + esp_rom_printf("INT!\n"); + portASSERT_IF_IN_ISR(); +} + +TEST_CASE("port must assert if in ISR context", "[freertos][ignore]") +{ + esp_err_t err = esp_register_freertos_tick_hook_for_cpu(testint_assert, xPortGetCoreID()); + TEST_ASSERT_EQUAL_HEX32(ESP_OK, err); + vTaskDelay(100 / portTICK_PERIOD_MS); + esp_deregister_freertos_tick_hook_for_cpu(testint_assert, xPortGetCoreID()); +} +#endif // !CONFIG_FREERTOS_SMP