Page 1 of 1

xTaskCreatePinnedToCore doesn't work for Core 1

Posted: Mon Sep 02, 2019 5:09 pm
by augunrik
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

Re: xTaskCreatePinnedToCore doesn't work for Core 1

Posted: Mon Sep 02, 2019 11:08 pm
by ESP_Angus
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.

Re: xTaskCreatePinnedToCore doesn't work for Core 1

Posted: Tue Sep 03, 2019 12:50 am
by RoverDog
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.

Re: xTaskCreatePinnedToCore doesn't work for Core 1

Posted: Tue Sep 03, 2019 6:03 pm
by augunrik
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.