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/lib/FreeRTOS-Kernel b/libraries/FreeRTOS/lib/FreeRTOS-Kernel index 6a303231e..2e588af95 160000 --- a/libraries/FreeRTOS/lib/FreeRTOS-Kernel +++ b/libraries/FreeRTOS/lib/FreeRTOS-Kernel @@ -1 +1 @@ -Subproject commit 6a303231eceaec08a26a7e534800ba4010cec58d +Subproject commit 2e588af95bad29aef577373512883370c9408c1c diff --git a/libraries/FreeRTOS/src/FreeRTOS.h b/libraries/FreeRTOS/src/FreeRTOS.h index 5827e5d21..1db1c270b 100644 --- a/libraries/FreeRTOS/src/FreeRTOS.h +++ b/libraries/FreeRTOS/src/FreeRTOS.h @@ -1,5 +1 @@ -#ifdef PICO_RP2350 -#error Sorry, FreeRTOS is not yet supported on the RP2350 in this core. -#else #include "../lib/FreeRTOS-Kernel/include/FreeRTOS.h" -#endif diff --git a/libraries/FreeRTOS/src/FreeRTOSConfig.h b/libraries/FreeRTOS/src/FreeRTOSConfig.h index 1e403f7f7..e28ec4d4a 100644 --- a/libraries/FreeRTOS/src/FreeRTOSConfig.h +++ b/libraries/FreeRTOS/src/FreeRTOSConfig.h @@ -200,6 +200,10 @@ extern unsigned long ulMainGetRunTimeCounterValue(void); #endif #endif +#define configENABLE_MPU 0 +#define configENABLE_TRUSTZONE 0 +#define configRUN_FREERTOS_SECURE_ONLY 1 +#define configENABLE_FPU 1 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #ifndef configLIBRARY_LOWEST_INTERRUPT_PRIORITY @@ -219,11 +223,16 @@ extern unsigned long ulMainGetRunTimeCounterValue(void); #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) #endif + /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #ifndef configMAX_SYSCALL_INTERRUPT_PRIORITY +#ifdef PICO_RP2350 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 16 +#else #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) #endif +#endif #ifndef configASSERT #ifdef __cplusplus diff --git a/libraries/FreeRTOS/src/mpu_syscall_numbers.h b/libraries/FreeRTOS/src/mpu_syscall_numbers.h new file mode 100644 index 000000000..fb175c2f2 --- /dev/null +++ b/libraries/FreeRTOS/src/mpu_syscall_numbers.h @@ -0,0 +1 @@ +#include "../lib/FreeRTOS-Kernel/include/mpu_syscall_numbers.h" diff --git a/libraries/FreeRTOS/src/mpu_wrappers_v2_asm.c b/libraries/FreeRTOS/src/mpu_wrappers_v2_asm.c new file mode 100644 index 000000000..97b24aead --- /dev/null +++ b/libraries/FreeRTOS/src/mpu_wrappers_v2_asm.c @@ -0,0 +1,3 @@ +#ifdef PICO_RP2350 +#include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/mpu_wrappers_v2_asm.c" +#endif diff --git a/libraries/FreeRTOS/src/port.c b/libraries/FreeRTOS/src/port.c index 2327f4627..944a548b7 100644 --- a/libraries/FreeRTOS/src/port.c +++ b/libraries/FreeRTOS/src/port.c @@ -1 +1,5 @@ +#ifdef PICO_RP2040 #include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/port.c" +#else +#include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/port.c" +#endif diff --git a/libraries/FreeRTOS/src/portasm.c b/libraries/FreeRTOS/src/portasm.c new file mode 100644 index 000000000..8f36df1f4 --- /dev/null +++ b/libraries/FreeRTOS/src/portasm.c @@ -0,0 +1,3 @@ +#ifdef PICO_RP2350 +#include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/portasm.c" +#endif diff --git a/libraries/FreeRTOS/src/portmacro.h b/libraries/FreeRTOS/src/portmacro.h index e769db5b0..3e549b080 100644 --- a/libraries/FreeRTOS/src/portmacro.h +++ b/libraries/FreeRTOS/src/portmacro.h @@ -1 +1,5 @@ +#ifdef PICO_RP2350 +#include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/portmacro.h" +#else #include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/include/portmacro.h" +#endif diff --git a/libraries/FreeRTOS/src/rp2040_config.h b/libraries/FreeRTOS/src/rp2040_config.h index a57b4421f..a99652775 100644 --- a/libraries/FreeRTOS/src/rp2040_config.h +++ b/libraries/FreeRTOS/src/rp2040_config.h @@ -1 +1,5 @@ +#ifdef PICO_RP2350 +#include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure//rp2040_config.h" +#else #include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/include/rp2040_config.h" +#endif 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(); + } } diff --git a/libraries/FreeRTOS/tests/switching/switching.ino b/libraries/FreeRTOS/tests/switching/switching.ino new file mode 100644 index 000000000..44aa5a142 --- /dev/null +++ b/libraries/FreeRTOS/tests/switching/switching.ino @@ -0,0 +1,57 @@ +// Released to the public domain +#include +#include +#include +#define STACK_SIZE 512 +#define CORE_0 (1 << 0) +#define CORE_1 (1 << 1) + +std::map eTaskStateName { {eReady, "Ready"}, { eRunning, "Running" }, {eBlocked, "Blocked"}, {eSuspended, "Suspended"}, {eDeleted, "Deleted"} }; +void ps() { + int tasks = uxTaskGetNumberOfTasks(); + TaskStatus_t *pxTaskStatusArray = new TaskStatus_t[tasks]; + unsigned long runtime; + tasks = uxTaskGetSystemState( pxTaskStatusArray, tasks, &runtime ); + Serial.printf("# Tasks: %d\n", tasks); + Serial.printf("%-3s %-16s %-10s %s %s\n", "ID", "NAME", "STATE", "PRIO", "CYCLES"); + for (int i = 0; i < tasks; i++) { + Serial.printf("%2d: %-16s %-10s %4d %lu\n", i, pxTaskStatusArray[i].pcTaskName, eTaskStateName[pxTaskStatusArray[i].eCurrentState], (int)pxTaskStatusArray[i].uxCurrentPriority, pxTaskStatusArray[i].ulRunTimeCounter); + } + delete[] pxTaskStatusArray; +} + +static TaskHandle_t l[16]; + +void loop() { + ps(); + delay(1000); +} + +#define LOOP(z) \ +void loop##z(void *params) {\ + (void) params;\ + while (true) {\ + srand(z);\ + int sum = 0;\ + for (int i = 0; i < 500000; i++) sum+= rand();\ + Serial.printf("L%d: %08x\n", z, sum);\ + delay(1000 + z * 10);\ + }\ +} + +LOOP(0); +LOOP(1); +LOOP(2); +LOOP(3); + + +void setup() { + xTaskCreate(loop0, "loop0", STACK_SIZE, NULL, 1, &l[0]); + vTaskCoreAffinitySet(l[0], CORE_0); +// xTaskCreate(loop1, "loop1", STACK_SIZE, NULL, 1, &l[1]); +// vTaskCoreAffinitySet(l[1], CORE_0); +// xTaskCreate(loop2, "loop2", STACK_SIZE, NULL, 1, &l[2]); +// vTaskCoreAffinitySet(l[2], CORE_0); +// xTaskCreate(loop3, "loop3", STACK_SIZE, NULL, 1, &l[3]); +// vTaskCoreAffinitySet(l[3], CORE_1); +} diff --git a/tests/common.sh b/tests/common.sh index 61a5db6fa..c8abe8c9f 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -8,7 +8,6 @@ function skip_ino() local skiplistrp2350="" if [ "$PICO_BOARD" == "rp2350" ]; then read -d '' skiplistrp2350 << EOL || true -/FreeRTOS/ /BTstackLib/ /JoystickBT/ /KeyboardBT/