diff --git a/cores/rp2040/_freertos.h b/cores/rp2040/_freertos.h index 74e1133bf..0c626f1ba 100644 --- a/cores/rp2040/_freertos.h +++ b/cores/rp2040/_freertos.h @@ -54,5 +54,8 @@ extern "C" { extern void __freertos_idle_other_core() __attribute__((weak)); extern void __freertos_resume_other_core() __attribute__((weak)); + + extern void __freertos_task_exit_critical() __attribute__((weak)); + extern void __freertos_task_enter_critical() __attribute__((weak)); } extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive = false); diff --git a/cores/rp2040/wiring_private.cpp b/cores/rp2040/wiring_private.cpp index b84d0d1ea..a91b4f9dd 100644 --- a/cores/rp2040/wiring_private.cpp +++ b/cores/rp2040/wiring_private.cpp @@ -23,6 +23,8 @@ #include #include #include +#include "_freertos.h" + // Support nested IRQ disable/re-enable #ifndef maxIRQs @@ -32,22 +34,29 @@ static uint32_t _irqStackTop[2] = { 0, 0 }; static uint32_t _irqStack[2][maxIRQs]; extern "C" void interrupts() { - auto core = get_core_num(); - if (!_irqStackTop[core]) { - // ERROR - return; + if (__freeRTOSinitted) { + __freertos_task_exit_critical(); + } else { + auto core = get_core_num(); + if (!_irqStackTop[core]) { + // ERROR + return; + } + restore_interrupts(_irqStack[core][--_irqStackTop[core]]); } - restore_interrupts(_irqStack[core][--_irqStackTop[core]]); } extern "C" void noInterrupts() { - auto core = get_core_num(); - if (_irqStackTop[core] == maxIRQs) { - // ERROR - panic("IRQ stack overflow"); + if (__freeRTOSinitted) { + __freertos_task_enter_critical(); + } else { + auto core = get_core_num(); + if (_irqStackTop[core] == maxIRQs) { + // ERROR + panic("IRQ stack overflow"); + } + _irqStack[core][_irqStackTop[core]++] = save_and_disable_interrupts(); } - - _irqStack[core][_irqStackTop[core]++] = save_and_disable_interrupts(); } // Only 1 GPIO IRQ callback for all pins, so we need to look at the pin it's for and diff --git a/libraries/FreeRTOS/src/variantHooks.cpp b/libraries/FreeRTOS/src/variantHooks.cpp index f4d2487cc..bc0846f05 100644 --- a/libraries/FreeRTOS/src/variantHooks.cpp +++ b/libraries/FreeRTOS/src/variantHooks.cpp @@ -91,6 +91,14 @@ extern "C" { bool __freertos_check_if_in_isr() { return portCHECK_IF_IN_ISR(); } + + void __freertos_task_exit_critical() { + taskEXIT_CRITICAL(); + } + + void __freertos_task_enter_critical() { + taskENTER_CRITICAL(); + } }