Add FreeRTOS support for RP2350 (#2406)

Pull in Raspberry Pi's custom RP2350 ARM and RISC-V ports for FreeRTOS.

Basic tests run, but stress mutex test is failing in unique and interesting
ways.

* Add simplified switching test catching task swap problem

* Freertosrp2350: use FreeRTOS macros in noInterrupts/interrupts when applicable. (#2456)
* Use FreeRTOS macros in noInterrupts/interrupts when applicable.
* Fixed calling taskEXIT_CRITICAL and taskENTER_CRITICAL
---------

Co-authored-by: fietser28 <fietser28@users.noreply.github.com>
This commit is contained in:
Earle F. Philhower, III 2024-09-16 16:56:22 -07:00 committed by GitHub
parent 5f6e4aff5c
commit a0b3876de4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 117 additions and 17 deletions

View file

@ -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);

View file

@ -23,6 +23,8 @@
#include <hardware/gpio.h>
#include <hardware/sync.h>
#include <map>
#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

@ -1 +1 @@
Subproject commit 6a303231eceaec08a26a7e534800ba4010cec58d
Subproject commit 2e588af95bad29aef577373512883370c9408c1c

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
#include "../lib/FreeRTOS-Kernel/include/mpu_syscall_numbers.h"

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
#ifdef PICO_RP2350
#include "../lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/portasm.c"
#endif

View file

@ -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

View file

@ -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

View file

@ -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();
}
}

View file

@ -0,0 +1,57 @@
// Released to the public domain
#include <FreeRTOS.h>
#include <task.h>
#include <map>
#define STACK_SIZE 512
#define CORE_0 (1 << 0)
#define CORE_1 (1 << 1)
std::map<eTaskState, const char *> 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);
}

View file

@ -8,7 +8,6 @@ function skip_ino()
local skiplistrp2350=""
if [ "$PICO_BOARD" == "rp2350" ]; then
read -d '' skiplistrp2350 << EOL || true
/FreeRTOS/
/BTstackLib/
/JoystickBT/
/KeyboardBT/