diff --git a/cores/rp2040/RP2040Support.h b/cores/rp2040/RP2040Support.h index 99ed1bd0e..05663725c 100644 --- a/cores/rp2040/RP2040Support.h +++ b/cores/rp2040/RP2040Support.h @@ -32,6 +32,18 @@ extern "C" volatile bool __otherCoreIdled; +// Halt the FreeRTOS PendSV task switching magic +extern "C" int __holdUpPendSV; + +// FreeRTOS weak functions, to be overridden when we really are running FreeRTOS +extern "C" { + extern void vTaskSuspendAll() __attribute__((weak)); + extern int32_t xTaskResumeAll() __attribute__((weak)); + typedef struct tskTaskControlBlock * TaskHandle_t; + extern void vTaskPreemptionDisable(TaskHandle_t p) __attribute__((weak)); + extern void vTaskPreemptionEnable(TaskHandle_t p) __attribute__((weak)); +} + class _MFIFO { public: _MFIFO() { /* noop */ }; @@ -86,6 +98,11 @@ class _MFIFO { if (!_multicore) { return; } + __holdUpPendSV = 1; + if (__isFreeRTOS) { + vTaskPreemptionDisable(nullptr); + vTaskSuspendAll(); + } mutex_enter_blocking(&_idleMutex); __otherCoreIdled = false; multicore_fifo_push_blocking(_GOTOSLEEP); @@ -98,6 +115,12 @@ class _MFIFO { } mutex_exit(&_idleMutex); __otherCoreIdled = false; + if (__isFreeRTOS) { + xTaskResumeAll(); + vTaskPreemptionEnable(nullptr); + } + __holdUpPendSV = 0; + // Other core will exit busy-loop and return to operation // once __otherCoreIdled == false. } diff --git a/cores/rp2040/main.cpp b/cores/rp2040/main.cpp index fc79b56c8..0896f3ff9 100644 --- a/cores/rp2040/main.cpp +++ b/cores/rp2040/main.cpp @@ -28,6 +28,7 @@ RP2040 rp2040; extern "C" { volatile bool __otherCoreIdled = false; + int __holdUpPendSV = 0; }; mutex_t _pioMutex; diff --git a/libraries/FreeRTOS/lib/FreeRTOS-Kernel b/libraries/FreeRTOS/lib/FreeRTOS-Kernel index f5fe79dac..0b55ee70a 160000 --- a/libraries/FreeRTOS/lib/FreeRTOS-Kernel +++ b/libraries/FreeRTOS/lib/FreeRTOS-Kernel @@ -1 +1 @@ -Subproject commit f5fe79dacd723b490ae9afe1b4f5ae45aae620c6 +Subproject commit 0b55ee70ad08ab10af77f49e48a7381ac81a6827 diff --git a/libraries/FreeRTOS/src/FreeRTOSConfig.h b/libraries/FreeRTOS/src/FreeRTOSConfig.h index ffb1a3c82..e0cd73e1e 100644 --- a/libraries/FreeRTOS/src/FreeRTOSConfig.h +++ b/libraries/FreeRTOS/src/FreeRTOSConfig.h @@ -26,6 +26,7 @@ #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_STATIC_ALLOCATION 0 #define configSTACK_DEPTH_TYPE uint32_t +#define configUSE_TASK_PREEMPTION_DISABLE 1 #define configUSE_NEWLIB_REENTRANT 1 #define configNEWLIB_REENTRANT_IS_DYNAMIC 0 /* Note that we have a different config option, portSET_IMPURE_PTR */ diff --git a/libraries/FreeRTOS/src/variantHooks.cpp b/libraries/FreeRTOS/src/variantHooks.cpp index a3d5efa7b..496246894 100644 --- a/libraries/FreeRTOS/src/variantHooks.cpp +++ b/libraries/FreeRTOS/src/variantHooks.cpp @@ -29,7 +29,6 @@ #include #include #include "tusb.h" -#define USB_TASK_IRQ 31 /* Raspberry PI Pico includes */ @@ -382,19 +381,11 @@ void vApplicationAssertHook() { #endif -static void __usb_irq() { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - vTaskNotifyGiveFromISR( __usbTask, &xHigherPriorityTaskWoken ); - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); -} - static void __usb(void *param) { (void) param; tusb_init(); - irq_set_exclusive_handler(USB_TASK_IRQ, __usb_irq); - irq_set_enabled(USB_TASK_IRQ, true); Serial.begin(115200);