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:
Sudeep Mohanty
2024-07-24 16:56:17 +02:00
parent 2e512fb8ee
commit d2e4722f5b
10 changed files with 102 additions and 13 deletions

View File

@@ -113,6 +113,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 --------------------
#if ( configNUMBER_OF_CORES > 1 )
@@ -187,6 +194,15 @@ void vPortTCBPreDeleteHook( 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 --------------------
#if ( configNUMBER_OF_CORES > 1 )

View File

@@ -168,6 +168,12 @@ BaseType_t xPortCheckIfInISR(void)
return uxInterruptNesting;
}
void vPortAssertIfInISR(void)
{
/* Assert if the interrupt nesting count is > 0 */
configASSERT(xPortCheckIfInISR() == 0);
}
// ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
@@ -373,7 +379,7 @@ FORCE_INLINE_ATTR UBaseType_t uxInitialiseStackTLS(UBaseType_t uxStackPointer, u
#if CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER
static void vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters)
{
__asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (inital) frame
__asm__ volatile(".cfi_undefined ra"); // tell to debugger that it's outermost (initial) frame
extern void __attribute__((noreturn)) panic_abort(const char *details);
static char DRAM_ATTR msg[80] = "FreeRTOS: FreeRTOS Task \"\0";
pxCode(pvParameters);
@@ -440,7 +446,7 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
HIGH ADDRESS
|---------------------------| <- pxTopOfStack on entry
| TLS Variables |
| ------------------------- | <- Start of useable stack
| ------------------------- | <- Start of usable stack
| Starting stack frame |
| ------------------------- | <- pxTopOfStack on return (which is the tasks current SP)
| | |

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 );
@@ -161,6 +168,14 @@ void vPortTCBPreDeleteHook( void *pxTCB );
#define portSET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK()
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
/**
* @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 to set the value of the INTLEVEL field ourselves
*/

View File

@@ -139,7 +139,7 @@ BaseType_t xPortEnterCriticalTimeout(portMUX_TYPE *lock, BaseType_t timeout)
void vPortExitCriticalIDF(portMUX_TYPE *lock)
{
/* This function may be called in a nested manner. Therefore, we only need
* to reenable interrupts if this is the last call to exit the critical. We
* to re-enable interrupts if this is the last call to exit the critical. We
* can use the nesting count to determine whether this is the last exit call.
*/
spinlock_release(lock);
@@ -204,6 +204,12 @@ BaseType_t xPortCheckIfInISR(void)
return ret;
}
void vPortAssertIfInISR(void)
{
/* Assert if the interrupt nesting count is > 0 */
configASSERT(xPortCheckIfInISR() == 0);
}
// ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
@@ -614,7 +620,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
| Coproc Save Area | (CPSA MUST BE FIRST)
| ------------------------- |
| TLS Variables |
| ------------------------- | <- Start of useable stack
| ------------------------- | <- Start of usable stack
| Starting stack frame |
| ------------------------- | <- pxTopOfStack on return (which is the tasks current SP)
| | |