Task delay without resetting the watchdog timer?

franck102
Posts: 8
Joined: Thu Mar 12, 2020 5:45 pm

Task delay without resetting the watchdog timer?

Postby franck102 » Thu Mar 12, 2020 6:19 pm

Hi all,

I am new to ESP32 programming, coming from Arduino, and I am struggling with the task watchdog timer.

The function below is a task handler, I am trying to init subsystems (SPIFFS, Wire...).
I want to try the inits in a loop, with a short delay between attempts, and I want the watchdog to reset the ESP after say 5 seconds.

Because vTaskDelay feeds the watchdog, I am using a busy loop below, which is kind of ugly: is there any way to replace my busy loop with a
delay_but_don't_reset_watchdog(100) ?

In other terms I'd like the task to yield to other tasks, but still get the watchdog to trigger after 5s.

Any suggestion?
Thanks!
Franck

Code: Select all

void setup()
{
    esp_task_wdt_init(5, true);
    xTaskCreatePinnedToCore(initSystems, "Init Systems", 10000, NULL, 3, &InitSystemsTask, 1);
}

Code: Select all

void initSystems(void *param)
{
    esp_task_wdt_add(NULL);

    // SPIFFS
    unsigned long now = millis();
    while (!SPIFFS.begin(true)) {
        while (millis() - now < 100u);
    }
    esp_task_wdt_reset();

   now = millis();
    while (!Wire.begin()) {
        debug("Failed to start Wire");
        while (millis() - now < 100u);
    }
    esp_task_wdt_reset();
  ...
}

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: Task delay without resetting the watchdog timer?

Postby ESP_Dazz » Thu Mar 12, 2020 7:10 pm

vTaskDelay() itself does not feed the Task Watchdog. It is the IDLE task that feeds the Task watchdog.

When you call vTaskDelay(), your current initSystems() task is put into the blocked state, allowing the operating system to schedule another task. If not other tasks are in the ready state, it will default to running the IDLE task (IDLE0 or IDLE1, one for each CPU) which has the lowest priority of 0 (thus why it only runs when no other higher priority task is in the ready state).

It is the act of the IDLE task running that feeds the Task Watchdog. Thus why the Task Watchdog triggers when a higher priority task is stuck in a loop (e.g., your initSystems() task when it fails to initalize SPIFFS/Wire)

However, its a bad idea to use the Task Watchdog to reset your chip in this case. Task Watchdog is meant to guard against stuck loops or overloaded CPU.

From you're description, it seems like what you're looking for is some sort of event that will trigger if your initSystems() task has not completed its initialization within a certain period of time (e.g., 5 seconds).

I suggest create another higher priority ctrlTask() instead, then have that ctrlTask() wait for a semaphore from initSystems() with a timeout of 5 seconds. If ctrlTask() doesn't get that semaphore within the prescribed time, have ctrlTask() print an error log and then call the chip reset function.

franck102
Posts: 8
Joined: Thu Mar 12, 2020 5:45 pm

Re: Task delay without resetting the watchdog timer?

Postby franck102 » Thu Mar 12, 2020 10:15 pm

ESP_Dazz wrote: vTaskDelay() itself does not feed the Task Watchdog. It is the IDLE task that feeds the Task watchdog.
Thanks, you made me realize two things
- the pattern of a separatecontrol task is indeed better for my use case
- I could in fact have used vTaskDelay in my task as written above, since as you rightly explain it wouldn’t feed the watchdog for that task, so the watchdog would still trigger (since I explicitly registered it to be monitored).

I should have read this first: https://docs.espressif.com/projects/esp ... /wdts.html

Franck

Who is online

Users browsing this forum: No registered users and 40 guests