Feed watchdog in Zephyr idle thread

Hi all,

Is there any way to use the Zephyr idle thread to feed the watchdog? I do that with freeRTOS and is an elegant way to feed the watchdog.

The other way is to create a task with a very low priority (just one step above the idle thread priority) and periodically feed it.

Thanks and kind regards,

Pedro.

  • Hi,

    The idle thread in Zephyr does nothing, so no, you cannot use that one for feeding the watchdog.

    You could do it from a very low priority thread (as you suggest), or from main, or signal from other threads to main and do it in main whenever you get the signals, or use another scheme.

    The important thing when using watchdogs, is to use them in a way which is useful for your use case. Typically that means signaling (or feeding) from the processes that should not freeze, and in such a way that even only one such process freezing would trigger the watchdog reset.

    Regards,
    Terje

  • Thank you Terje! 

    I will take your advices.

    Kind regards,

    Pedro.

  • Hi Pedro,

    Are you using the hardware watchdog ?

    I am looking for examples on how to configure it and use it to prevent lock-ups.

    All the examples I found were about task_watchdog.

    zephyr\samples\drivers\watchdog

    zephyr\samples\subsys\task_wdt

    Thank you.

    Kind regards

    Mohamed

  • Hi Mohamed,

    Yes, I'm using hardware watchdog.

    Use this for reference:

    #include <drivers/watchdog.h>
    #include <logging/log.h>
    
    #define WDT_MAX_WINDOW  10000U
    
    LOG_MODULE_REGISTER(wdt);
    
    static const struct device *wdt = DEVICE_DT_GET(DT_NODELABEL(wdt0));
    static int wdt_channel_id;
    
    int wdt_wdtSetup() {
    	int err;
    
    	if (!device_is_ready(wdt) || wdt == NULL)
    	{
    		LOG_WRN("Watchdog not ready");
    		return -EIO;
    	}
    
    	struct wdt_timeout_cfg wdt_config = {
    	    /* Reset SoC when watchdog timer expires. */
    	    .flags = WDT_FLAG_RESET_SOC,
    
    	    /* Expire watchdog after max window */
    	    .window.min = 0U,
    	    .window.max = WDT_MAX_WINDOW};
    
    	wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
    	if (wdt_channel_id < 0)
    	{
    		LOG_ERR("Watchdog install error.");
    		return wdt_channel_id;
    	}
    
    	err = wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG);
    	if (err)
    	{
    		LOG_ERR("Watchdog setup error");
    		return err;
    	}
    
    	return 0;
    }
    
    void wdt_wdtFeed() {
    	wdt_feed(wdt, wdt_channel_id);
    }
    

    Remember to enable wdt in prj.conf

    CONFIG_WATCHDOG=y
    CONFIG_WDT_LOG_LEVEL_DBG=y
    CONFIG_WDT_DISABLE_AT_BOOT=n

    Regards,

    Pedro.

  • Thank you Pedro.

    Much appreciated.

    Am I right in assuming #define WDT_MAX_WINDOW  10000U is in [ms] i.e. the maximum timeout is 10 seconds? This is not the absolute maximum timeout period.

    I believe the absolute maximum timeout period allowed is dictated by the size of the CRV register which is 0xFFFFFFFF * 32768 seconds.

    Kind regards

    Mohamed

Related