mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(freertos): Incorrect assert in FreeRTOS port layer when not in ISR context
This commit fixes an issue where in the FreeRTOS port layer would cause the portASSERT_IF_IN_ISR() assert check to fail even when the system is not in an interrupt context.
This commit is contained in:
parent
9468f1939b
commit
e9e0e250a6
@ -85,6 +85,13 @@ typedef spinlock_t portMUX_TYPE; /**< Spi
|
|||||||
|
|
||||||
BaseType_t xPortCheckIfInISR(void);
|
BaseType_t xPortCheckIfInISR(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert if in ISR context
|
||||||
|
*
|
||||||
|
* - Asserts on xPortCheckIfInISR() internally
|
||||||
|
*/
|
||||||
|
void vPortAssertIfInISR(void);
|
||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -148,6 +155,15 @@ void vPortCleanUpTCB ( void *pxTCB );
|
|||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(1)
|
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(1)
|
||||||
#define portRESTORE_INTERRUPTS(x) vPortClearInterruptMask(x)
|
#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 --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
#define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock)
|
#define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock)
|
||||||
|
@ -279,6 +279,12 @@ BaseType_t xPortCheckIfInISR(void)
|
|||||||
return uxInterruptNesting;
|
return uxInterruptNesting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vPortAssertIfInISR(void)
|
||||||
|
{
|
||||||
|
/* Assert if the interrupt nesting count is > 0 */
|
||||||
|
configASSERT(xPortCheckIfInISR() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
void IRAM_ATTR vPortTakeLock( portMUX_TYPE *lock )
|
void IRAM_ATTR vPortTakeLock( portMUX_TYPE *lock )
|
||||||
|
@ -95,6 +95,13 @@ typedef spinlock_t portMUX_TYPE; /**< Spi
|
|||||||
|
|
||||||
BaseType_t xPortCheckIfInISR(void);
|
BaseType_t xPortCheckIfInISR(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert if in ISR context
|
||||||
|
*
|
||||||
|
* - Asserts on xPortCheckIfInISR() internally
|
||||||
|
*/
|
||||||
|
void vPortAssertIfInISR(void);
|
||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
UBaseType_t uxPortEnterCriticalFromISR( void );
|
UBaseType_t uxPortEnterCriticalFromISR( void );
|
||||||
@ -151,6 +158,14 @@ void vPortCleanUpTCB ( void *pxTCB );
|
|||||||
XTOS_SET_INTLEVEL(0); \
|
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
|
Note: XTOS_RESTORE_INTLEVEL() will overwrite entire PS register on XEA2. So we need ot make the value INTLEVEL field ourselves
|
||||||
*/
|
*/
|
||||||
|
@ -313,6 +313,12 @@ BaseType_t xPortCheckIfInISR(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vPortAssertIfInISR(void)
|
||||||
|
{
|
||||||
|
/* Assert if the interrupt nesting count is > 0 */
|
||||||
|
configASSERT(xPortCheckIfInISR() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
void vPortTakeLock( portMUX_TYPE *lock )
|
void vPortTakeLock( portMUX_TYPE *lock )
|
||||||
|
@ -132,6 +132,13 @@ typedef uint32_t TickType_t;
|
|||||||
*/
|
*/
|
||||||
BaseType_t xPortInIsrContext(void);
|
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
|
* @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 portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) vPortClearInterruptMask(uxSavedStatusValue)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) vPortClearInterruptMask(uxSavedStatusValue)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert if in ISR context
|
||||||
|
*/
|
||||||
|
#define portASSERT_IF_IN_ISR() vPortAssertIfInISR()
|
||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
|
||||||
#define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();}
|
#define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();}
|
||||||
|
@ -229,6 +229,12 @@ BaseType_t xPortInIsrContext(void)
|
|||||||
return uxInterruptNesting;
|
return uxInterruptNesting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vPortAssertIfInISR(void)
|
||||||
|
{
|
||||||
|
/* Assert if the interrupt nesting count is > 0 */
|
||||||
|
configASSERT(xPortInIsrContext() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
|
BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
|
||||||
{
|
{
|
||||||
/* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */
|
/* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */
|
||||||
|
@ -165,12 +165,9 @@ typedef uint32_t TickType_t;
|
|||||||
BaseType_t xPortInIsrContext(void);
|
BaseType_t xPortInIsrContext(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Asserts if in ISR context
|
* @brief Assert if in ISR context
|
||||||
*
|
*
|
||||||
* - Asserts on xPortInIsrContext() internally
|
* - 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);
|
void vPortAssertIfInISR(void);
|
||||||
|
|
||||||
@ -444,6 +441,9 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void);
|
|||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMaskFromISR()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMaskFromISR()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(prev_level) vPortClearInterruptMaskFromISR(prev_level)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(prev_level) vPortClearInterruptMaskFromISR(prev_level)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert if in ISR context
|
||||||
|
*/
|
||||||
#define portASSERT_IF_IN_ISR() vPortAssertIfInISR()
|
#define portASSERT_IF_IN_ISR() vPortAssertIfInISR()
|
||||||
|
|
||||||
// ------------------ Critical Sections --------------------
|
// ------------------ Critical Sections --------------------
|
||||||
|
@ -282,7 +282,8 @@ BaseType_t xPortInIsrContext(void)
|
|||||||
|
|
||||||
void vPortAssertIfInISR(void)
|
void vPortAssertIfInISR(void)
|
||||||
{
|
{
|
||||||
configASSERT(xPortInIsrContext());
|
/* Assert if the interrupt nesting count is > 0 */
|
||||||
|
configASSERT(xPortInIsrContext() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
|
BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
|
||||||
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -62,3 +62,20 @@ TEST_CASE("xPortInIsrContext test", "[freertos]")
|
|||||||
|
|
||||||
|
|
||||||
#endif
|
#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
|
||||||
|
Loading…
Reference in New Issue
Block a user