xTaskCreatePinnedToCore doesn't work for Core 1

augunrik
Posts: 2
Joined: Mon Sep 02, 2019 4:53 pm

xTaskCreatePinnedToCore doesn't work for Core 1

Postby augunrik » Mon Sep 02, 2019 5:09 pm

Hi!

I'm currently debugging this piece of code for hours and can't see my fault - does anyone of you maybe have an idea?

Code: Select all

static int taskCore = 1;

void coreTask(void *pvParameters) {
  String taskMessage = "Task running on core " + xPortGetCoreID();

  while (true) {
    Serial.println(taskMessage);
    delay(1000);
  }
}

void setup() {
  Serial.begin(115200);

  int temp = xTaskCreatePinnedToCore(
      coreTask,   /* Function to implement the task */
      "coreTask", /* Name of the task */
      1000,       /* Stack size in words */
      NULL,       /* Task input parameter */
      0,          /* Priority of the task */
      NULL,       /* Task handle. */
      taskCore);  /* Core where the task should run */

  if(temp) {
    Serial.println("Task created...");
  } else {
    Serial.printf("Couldn't create task %i", temp);
  }
}

void loop() {}
So if I set

Code: Select all

taskCore
to zero, it works flawlessly. If I set it to 1 - the device boots, "Task created..." is being printed but no life sign of the task can be seen on the serial port. I also tried to toggle a pin in the task - same picture (works with core=0, doesn't work core=1).
I'm using platformio with the platformio.ini

Code: Select all

[env:esp32dev]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_speed = 115200
build_flags = -DCORE_DEBUG_LEVEL=5
Is my brain faulty? My code or my esp32? Maybe someone can give me a pointer or try it out with his ESP-WROOM32.

Thanks!
Mark

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: xTaskCreatePinnedToCore doesn't work for Core 1

Postby ESP_Angus » Mon Sep 02, 2019 11:08 pm

Hi Mark,

ESP-IDF uses FreeRTOS which is a real-time operating system. This means that the highest priority task that can run on a CPU will *always* be the task which runs on that CPU.

The root cause is a combination of two things:

Code: Select all

      0,          /* Priority of the task */
And

Code: Select all

void loop() {}
The task which runs setup() and loop() is created on core 1 with priority 1.

That task is currently running loop() forever (literally just calling the loop() function over and over) at priority 1 on core 1. Because the other task is priority 0, and the loop task never yields the CPU, the other task never gets to run.

To fix this you can do one of two things (probably best to do both):
  • Raise your new task's priority higher than 1 (this is a good idea anyhow as the Idle task runs at priority 0 so other weird things can happen to tasks with priority 0).
  • Change loop() to something like "void loop() { vTaskDelay(100); }" so it yields the CPU, or even "void loop() { vTaskDelete(NULL); }" to delete that task and free its resources if you don't plan to use it at all.

RoverDog
Posts: 8
Joined: Fri Aug 30, 2019 3:38 am

Re: xTaskCreatePinnedToCore doesn't work for Core 1

Postby RoverDog » Tue Sep 03, 2019 12:50 am

I found this YouTube tutorial very handy : https://www.youtube.com/watch?v=k_D_Qu0cgu8

1st problem I ran into was stack size in the xTaskCreatePinnedToCore parameters. Changed it from 1000 to 4000. Next I experienced watchdog timer issues, but that is a different problem altogether. Since things like WiFi is handled by core 0, I try to let core 1 do timing critical tasks. Now I have no more issues with running multiple tasks on both cores.

augunrik
Posts: 2
Joined: Mon Sep 02, 2019 4:53 pm

Re: xTaskCreatePinnedToCore doesn't work for Core 1

Postby augunrik » Tue Sep 03, 2019 6:03 pm

Thank you very much, both of you!

I've tested it, it works and I facepalmed myself. I understand the solution.
I somehow assumed that the loop would be more cooperative.

Who is online

Users browsing this forum: No registered users and 66 guests