Feeding watchdog from a thread

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
jedo-tm
Posts: 1
Joined: Sun May 22, 2022 8:31 pm

Feeding watchdog from a thread

Post by jedo-tm » Sun May 22, 2022 8:44 pm

When I feed the watchdog from thread that is not __main__ it has no effect and the board (ESP32 / micropython 1.18) reset.

I the example below I created a class "service" which executed a function at a certain interval. In the example below the wathcdog feed function is caled every second, however the board resets after 10 sec ( the watchdogs timeout )

Must the watchdog be feed from the main thread?

Code: Select all

import machine
import time
import _thread

class service:
    def __init__(self,function,delay=10):
        self.function = function
        self.delay=delay
        self.shutdown=False
        
    def main_loop(self):
        while not self.shutdown:
            self.function()
            for i in range(self.delay*10):
                time.sleep_ms(100)
    def start(self):
        self.shutdown=False
        try:
            print("Starting service. Function '%s' executed every %i sec" % (self.function.__name__,self.delay))
        except:
            print("Starting service. Function '%s' executed every %i sec" % ("bound method",self.delay))
        self.thread=_thread.start_new_thread(self.main_loop,())
    
    def stop(self):
        self.shutdown=True
        
wd_timeout = 10000
wd = machine.WDT(id=0, timeout=wd_timeout)
service_wd=service(function=wd.feed,delay=1)
service_wd.start()


User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Feeding watchdog from a thread

Post by pythoncoder » Mon May 23, 2022 8:26 am

The purpose of a WDT is to reset the board if the program has stopped running. Feeding the WDT in a separate thread defeats this aim: the main thread may have hung while the WDT thread continues to execute.

wd.feed() commands should be distributed around your main program in such a way that, if the program halts for any reason, the WDT will time out.
Peter Hinch
Index to my micropython libraries.

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: Feeding watchdog from a thread

Post by karfas » Mon May 23, 2022 11:17 am

Depending upon the way the micropython threads are implemented (I have no idea) it might be required to create the watchdog instance per thread.
The underlying esp_task_wdt_add() gets NULL for the "task" to monitor, meaning the current task. In the case a thread is a "task" on its own (?) this will obviously not work. See ports/esp32/machine_WDT.c for the micropython implementation and https://docs.espressif.com/projects/esp ... /wdts.html for the ESP-IDF calls.
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Feeding watchdog from a thread

Post by pythoncoder » Tue May 24, 2022 12:08 pm

My comment was to caution against adding a thread (to a single-threaded program) whose only purpose was to feed the dog. Using a WDT in a multi-threaded program provides difficulties of its own. How do you detect if one thread has stopped running? Not an insoluble problem, but one which would demand careful analysis.
Peter Hinch
Index to my micropython libraries.

Post Reply