Task on second core only running when debugger is attached

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;
    }
}

What happens if you do not set the core affinity? Does it not run at all? What are the task priorities?

I’d also suggest to reach out to Raspberry Pi maintainers as it is a new FreeRTOS port from them.

1 Like

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.

And just to make sure that you have enabled preemption and time slicing?

Yes, preemption, time slicing and configNUM_CORES are all set.

Then I guess it Raspberry Pi folks can probably answer that better.

More out of curiosity - what happens if you create both the main task and led task from vLaunch instead of having the main task create the led task?