Merge branch 'fix/freertos_port_assert_in_isr_bug_v5.0' into 'release/v5.0'

fix(freertos): Incorrect assert in FreeRTOS port layer when not in ISR context (v5.0)

See merge request espressif/esp-idf!32375
This commit is contained in:
Jiang Jiang Jian 2024-08-28 11:39:25 +08:00
commit abc7c13430
9 changed files with 85 additions and 6 deletions

View File

@ -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)

View File

@ -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 )

View File

@ -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
*/

View File

@ -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 )

View File

@ -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();}

View File

@ -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 */

View File

@ -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 --------------------

View File

@ -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)

View File

@ -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