diff --git a/components/freertos/include/freertos/portmacro.h b/components/freertos/include/freertos/portmacro.h index 908206eb37..ab83b0e05a 100644 --- a/components/freertos/include/freertos/portmacro.h +++ b/components/freertos/include/freertos/portmacro.h @@ -167,6 +167,9 @@ typedef struct { #define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0) #define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0) +#define portASSERT_IF_IN_ISR() vPortAssertIfInISR() +void vPortAssertIfInISR(); + #define portCRITICAL_NESTING_IN_TCB 1 /* @@ -213,6 +216,7 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux); // Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack. // They can be called from interrupts too. +//NOT SMP-COMPATIBLE! Use only if all you want is to disable the interrupts locally! static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); return state; } #define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0) diff --git a/components/freertos/port.c b/components/freertos/port.c index afa4978639..6117a2804e 100644 --- a/components/freertos/port.c +++ b/components/freertos/port.c @@ -248,14 +248,17 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMOR #endif +void vPortAssertIfInISR() +{ + configASSERT(port_interruptNesting[xPortGetCoreID()]==0) +} + /* * Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare * *mux to compare, and if it's the same, will set *mux to set. It will return the old value * of *addr. * - * Note: the NOPs are needed on the ESP31 processor but superfluous on the ESP32. - * * Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the * *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the * ESP32, though. (Would show up directly if it did because the magic wouldn't match.) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 92970b582a..153fa3f03f 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -3763,7 +3763,7 @@ scheduler will re-enable the interrupts instead. */ { if( xSchedulerRunning != pdFALSE ) { - portENTER_CRITICAL_NESTED(pxCurrentTCB[ xPortGetCoreID() ]->uxOldInterruptState); + pxCurrentTCB[ xPortGetCoreID() ]->uxOldInterruptState=portENTER_CRITICAL_NESTED(); } #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG vPortCPUAcquireMutex( mux, function, line ); @@ -3775,16 +3775,23 @@ scheduler will re-enable the interrupts instead. */ { ( pxCurrentTCB[ xPortGetCoreID() ]->uxCriticalNesting )++; + /* This is not the interrupt safe version of the enter critical function so assert() if it is being called from an interrupt context. Only API functions that end in "FromISR" can be used in an interrupt. Only assert if the critical nesting count is 1 to protect against recursive calls if the assert function also uses a critical section. */ + /* DISABLED in the esp32 port - because of SMP, vTaskEnterCritical + has to be used in way more places than before, and some are called + both from ISR as well as non-ISR code, thus we re-organized + vTaskEnterCritical to also work in ISRs. */ +#if 0 if( pxCurrentTCB[ xPortGetCoreID() ]->uxCriticalNesting == 1 ) { portASSERT_IF_IN_ISR(); } +#endif } else