Hi, I’m having some weird issues trying to use FreeRTOS on the rp2350. I have a pretty simple setup with a main task and a second task (led_task). The main task is tied to core 0 with a call to vTaskCoreAffinitySet. The second task will only run if the core affinity is set to core 0, unless I have a debugger attached, then the task will run fine on core 1 with the right vTaskCoreAffinitySet call. Would love to hear from others with more experience on how I can debug this situation.
void vLaunch(void)
{
TaskHandle_t task;
xTaskCreate(main_task, "MainThread", MAIN_TASK_STACK_SIZE, NULL, MAIN_TASK_PRIORITY, &task);
LOG_INFO("Main task created\n");
vTaskCoreAffinitySet(task, (1 << 0));
/* Start the tasks and timer running. */
vTaskStartScheduler();
}
void main_task(__unused void* params)
{
auto result = xTaskCreate(led_task, "LedTask", LED_TASK_STACK_SIZE, NULL, LED_TASK_PRIORITY, &led_task_handle);
LOG_INFO("Led task created\n");
vTaskCoreAffinitySet(led_task_handle, (1 << 0));
if (result != pdPASS)
{
LOG_ERROR("Failed to create led task\n");
}
int count = 0;
while (true)
{
static int last_core_id = -1;
if (portGET_CORE_ID() != last_core_id)
{
last_core_id = portGET_CORE_ID();
LOG_INFO("main task is on core %d\n", last_core_id);
}
LOG_INFO("Hello from main task count=%u\n", count++);
vTaskDelay(3000);
xTaskNotifyGive(led_task_handle);
taskYIELD();
}
}
void led_task(void* params)
{
LOG_INFO("Hello from led task\n");
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
static int last_core_id = -1;
if (portGET_CORE_ID() != last_core_id)
{
last_core_id = portGET_CORE_ID();
LOG_INFO("led task is on core %d\n", last_core_id);
}
int count = 0;
while (true)
{
pico_set_led(count % 2);
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
LOG_INFO("Hello from led task\n");
++count;
}
}
So, if I do not set a task affinity for the main task, that one will not run at all, and the only affinity mask that seems to work is (1 <<0), other affinities won’t run.
If I do not set a task affinity for led_task, or if I set the affinity to (1 << 0), then it runs on core 0.
Thanks, I will also reach out to RPi about this. They do have a FreeRTOS example that runs on both cores, though it uses async_context_freertos_t to schedule the worker task on a different core (though I’m not sure if you can choose which core the task will use). I guess it might be possible they haven’t fully implemented SMP functionality for the new chip yet.
Thank you for sharing these details. What are the values of MAIN_TASK_PRIORITY and LED_TASK_PRIORITY? Also, just for testing, can you try to remove log statements and instead try to blink LEDs?
MAIN_TASK_PRIORITY was tskIDLE_PRIORITY + 5UL and LED_TASK_PRIORITY was tskIDLE_PRIORITY + 2UL
I’ve tried with all sort of different priorities and it didn’t seem to have an impact.
Now the interesting part: I’ve removed the log statement but that didn’t seem to help, but it made me move my GPIO init calls to my int main() so that it looked like this:
int main()
{
stdio_init_all();
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
for (int i = 0; i < 5; i++)
{
gpio_put(PICO_DEFAULT_LED_PIN, 1);
sleep_ms(250);
gpio_put(PICO_DEFAULT_LED_PIN, 0);
sleep_ms(250);
}
...
and that fixed the issue. I did some more digging and simply adding a sleep_ms(1) call right after boot fixes the issue. I’m guessing the delay caused by the debugger attaching was achieving the same thing.