ESP32 dual core gives task_wdt ... did not reset the watchdog in time

shome_das
Posts: 1
Joined: Sun May 05, 2019 6:25 am

ESP32 dual core gives task_wdt ... did not reset the watchdog in time

Postby shome_das » Sun May 05, 2019 6:50 am

I am trying to get a basic dual core application running(code attached below). It gives me error
TasE (10179) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time.

I need a way to get rid of this watchdog timer error. In my actual program I need throughput of task in each core to be nearly 2KHz

If I add

Code: Select all

VTaskDelay(1)
to the tasks then no error occurs. Does it imply that VtaskDelay(1) = 1milisecond?
If it means 1 milisec then I cant use it in my code as the throughtput needs to be nearly 2KHz and any delays can be only in microseconds. How can I add delay in microseconds?

Also it seems that core 1 task is executed rarely. core 0 task is executed most of the time. How to ensure that both core tasks run properly.

Code: Select all

TaskHandle_t Task1;
TaskHandle_t Task2;

void setup() {
  Serial.begin(9600); 
  //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
  xTaskCreatePinnedToCore(
                    Task1code,   /* Task function. */
                    "Task1",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &Task1,      /* Task handle to keep track of created task */
                    0);          /* pin task to core 0 */                  
  delay(500); 

  //create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
  xTaskCreatePinnedToCore(
                    Task2code,   /* Task function. */
                    "Task2",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &Task2,      /* Task handle to keep track of created task */
                    1);          /* pin task to core 1 */
    delay(500); 
}

void Task1code( void * pvParameters ){
  for(;;){
  Serial.print("Task1 running on core ");
  Serial.println(xPortGetCoreID());
  } 
}

void Task2code( void * pvParameters ){
  for(;;){
  Serial.print("Task2 running on core ");
  Serial.println(xPortGetCoreID());
  }
}

void loop() { 
}
Error message:

Code: Select all

TasE (10179) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (10179) task_wdt:  - IDLE0 (CPU 0)
E (10179) task_wdt: Tasks currently running:
E (10179) task_wdt: CPU 0: Task1
E (10179) task_wdt: CPU 1: loopTask
E (10179) task_wdt: AbortinGuru Meditation Error: Core  0 panic'ed (Interrupt wdt timeout on CPU0)
output shows that most of the time core 0 code is executed.

Code: Select all

Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0
Task1 running on core 0

ESP_Sprite
Posts: 2719
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 dual core gives task_wdt ... did not reset the watchdog in time

Postby ESP_Sprite » Sun May 05, 2019 9:59 am

In esp_idf (which the arduino environment is built on, so you can use it there as well) you'd normally use either a timer peripheral to un-block a task faster than 1KHz, or use esp_timer calls. The freertos delay functions aren't well-suited for this, as you found out.

boarchuz
Posts: 97
Joined: Tue Aug 21, 2018 5:28 am

Re: ESP32 dual core gives task_wdt ... did not reset the watchdog in time

Postby boarchuz » Sun May 05, 2019 11:35 am

Code: Select all

void loop() { }
The loopTask is pinned to CPU1. This means that CPU1 is very busy doing your empty loop() over and over and over again, so Task2 (which is also pinned to CPU1) is starved of CPU time.
There are two easy solutions. Tell the scheduler to make it idle, or just delete the task:

Code: Select all

void loop() {
  vTaskDelay(portMAX_DELAY);
  //OR
  vTaskDelete(NULL);
}
As for the watchdog thing, the simplest option would be to try adding a yield() (aka vTaskYield()) where necessary. eg.

Code: Select all

void Task1code( void * pvParameters ){
  for(;;){
    Serial.print("Task1 running on core ");
    Serial.println(xPortGetCoreID());
    yield();
  }
}
Oh and increase the priority of both tasks, at least so they're higher than idle (1). Try 5-10.

Who is online

Users browsing this forum: No registered users and 2 guests