Question Details

No question body available.

Tags

c embedded esp32 rtos watchdog

Answers (3)

November 10, 2025 Score: 2 Rep: 222,219 Quality: Low Completeness: 20%

Watchdog peripherals typically don't allow disabling of the watchdog because that would be a safety hazard.

In the ideal world, you only update the watchdog once, at the top of the for-ever loop in main(). In practice you might not be able to do that in all programs however, in case there are time consuming tasks. The work-around then is to also update the watchdog periodically from inside that time consuming task.

Now if this is all in external code beyond your control, then that code wasn't written properly with real-time systems in mind. There exists no trick you should use to fix such bad code - the solution then is to re-write the bad code. If the function is waiting for hardware to complete something, then it should have been written in a polling manner that returns a status code, rather than as a blocking function which is unacceptable in most contexts.

November 10, 2025 Score: 1 Rep: 94,451 Quality: Medium Completeness: 80%

There are any number if solutions if varying sophistication and robustness.

You could create a higher priority task that will periodically preempt the "busy" task and reset the watchdog. This task should run temporarily and be started and stopped either side of the potentially busy makeinference call.

Or perhaps more simply create a periodic timer, the event handler of which resets the watchdog, and similarly start and stop that timer either side of the makeinference call

Arguably the watchdog maintainer task solution is preferable to the timer handler because it can be set to a priority level just above that of the busy task, so that other tasks remain protected, whereas a timer event handler will preempt all tasks and may cause a failed task to remain undetected.

In both cases you should have a counter in the maintainer task, so that the inference task can be protected by a "software watchdog". For example you might limit the maintainer to running for say 60 seconds at a time, and stop maintaining the watchdog when that is exceeded.

A further very simple alternative is to ensure round-robin scheduling is enabled and simply make the inference loop task the same priority level as the watchdog maintenance task.

More generally, a better watchdog strategy could be used. For example implement a software watchdog system, where a separate task handles the software watchdogs, and only when all are maintained, it would itself maintain the hardware watchdog. Such a task would run at a high priority, but allow each task to have different timeout periods longer or shorter than the hardware watchdog. When a task fails to maintain its own timer, the watchdog task would either stop maintaining the hardware watchdog or issue a hardware reset directly, or take some other remedial action.

Note that making the watchdog maintenance a high priority task is only acceptable when that task implements individual task software watchdogs, otherwise you defeat the purpose of the watchdog since all lower priority tasks could fail while the hardware watchdog continues to be maintained oblivious.

So there are "quick and dirty" solutions that will get you working, and better more complex solutions that will improve the robustness of your system holistically rather then just working around this particular issue. In order from (subjectively) worst to best solution I would suggest:

  • Round-robin/time-slice scheduling and non-real-time, "busy" or non-deterministic tasks running at the same priority as the watchdog maintenance. None of the tasks at that level will be protected by the watchdog.
  • Temporary periodic timer with handler that maintains the watchdog. Defeats protection for all tasks while the high priority timer event is maintaining the watchdog. If the task that sets it stalls indefinitely, protection will be defeated completely unless a timeout is additionally implemented in the handler.
  • Temporary watchdog maintenance task at priority just above the "busy" task (or same priority with time-slicing/round-robin), Tasks at or below the priority of the maintenance task can stall indefinitely without watchdogging - again a timeout could be used to prevent that.
  • A high priority task maintaining the hardware watchdog while maintaining also a software watchdog for each other task running. Each task may then set its own watchdog period independent of the hardware watchdog, and on failure it is possible to log or report which task failed to reset its soft-watchdog in time.

In this last case, the watchdog task would run periodically and increment a counter for each task, if the counter exceeds the limit set for that task, then the remedial action should be taken. The tasks themselves must reset their counter before expiry. The remedial action could be task specific, but as a minimum suspension of hardware watchdog maintenance or direct system restart would be appropriate.

November 10, 2025 Score: 1 Rep: 94,451 Quality: Medium Completeness: 80%

My previous advice is generally applicable to most RTOS environments with a hardware watchdog timer which directly resets the processor. However looking at https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/wdts.html the situation with ESP32 and ESP-IDF is somewhat different. It already supports a kind of software watchdog, although perhaps not as flexible as the one I suggested.

In the IDF API you nominate one or more tasks for watchdog monitoring and each task must then reset the watchdog within the single watchdog timeout period. That is the problem here, the single watchdog period. I assume it works by requiring all registered tasks to issue a reset for the TWDT to finally issue the hardware WDT reset.

All you are doing by calling esptaskwdtdelete(idle) is removing that task from the list of resetters. The underlying hardware watchdog will continue to run. It is unusual to be able to stop a watchdog timer once started, but not unheard of. In this case the watchdog does not reset the processor, but issues an interrupt. In such a case it is possible to defeat a running watchdog, but replacing the interrupt. I suspect in this case rather then delete/add the idle task, you need to esptaskwdtdeinit() then esptaskwdtinit() the watchdog in its entirety. Alternatively you can delete and add but you need at least one other higher priority periodic task to be registered to the TWDT that will continue to reset it.

The latter should be the preferred solution since deinitialising the TWDT removes all protection where as delete/add removes protection.

So in addition to my earlier advice which may still be adapted to the peculiarities of the ESP-IDF TWDT mechanism, there is another possibility, where you simply create a higher priority periodic task that calls esptaskwdtreset() and add that to the TWDT (esptaskwdt_add()), then you can delete/add the idle task because there is another task continuing to maintain the IWDT. When both the maintainer task and the idle thread are added, both must issue the reset to maintain the watchdog.

By making the maintainer task as low a priority as possible (but higher and the inference task or equal is time slicing is enabled), then you will minimise the reduction in protection to only those tasks below that priority.

However a more robust integrity strategy would be advised as described in my previous answer.