This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

WDT and Error Handler

This ticket started as a mail thread so I add it here so no data are missing:

============================================================================================================================ 

Yes I based my code from this sample code so I use the exact same steps and variables (5 seconds timeout). I do not use the wdt_feed() and it still works and I assume that if we do not feed the dog it will hang after 5 seconds. But it does not do that but I can see sporadic reboot within one hour.

For the callback issue I do use a debugger and it never enter the callback.

So having a WDT driver that do not needs feed, no working callback and sporadic restarts seems to be a broken implementation in Zephyr!

How can you fix this and when?

============================================================================================================================

Regarding the watchdog - there is a nice sample presenting how to use the API:

https://github.com/zephyrproject-rtos/zephyr/blob/master/samples/drivers/watchdog/src/main.c

Have you tried to follow this one?

Basically you need to call wdt_install_timeout(), then wdt_setup(), and then feed the watchdog with wdt_feed() within the time configured when installing the timeout.

And when checking if the watchdog callback function is called, remember that this function is called two cycles of the 32 kHz clock before the reset is done, so it is a very little time to do something. In case you’d want to set a breakpoint in this function, you’ll need to use the WDT_OPT_PAUSE_HALTED_BY_DBG option.

============================================================================================================================

I have two question regarding WTD and Error-handler.

  1. I have enabled WDT in Zephyr and implemented the setup and enable of the WDT and it seems to work, but …
    I do not use the wdt_feed() api but still it works but I could get sporadic restart within an hour a so. I also note that the callback function is not called when watchdog has expired.
  2. For the Error-Handler; And there are a lot of different fault handler for different failure and exceptions. And I want to enable reset when this happens. So is there any support for reset when we end up in any error handler?
Parents Reply Children
  • https://github.com/zephyrproject-rtos/zephyr/blob/master/include/misc/util.h. Look up the definition of BIT(). And then look at this www.wolframalpha.com/.../. Then maybe it will be more apparent that BIT(0) and 0 is not the same. I will see if I have time to reproduce your issue later, but I'm a little busy right now.

  • Even if I was clear how the configuration works you still want me to experiment with something that do not make sense. So I did test your suggestion and it fails because of my explanation above. The bit configuration are bitmask so the drivers knows what to configure. Bit 0 controls the sleep wdt and it should be set to 0. And this are done with wdt_setup(system_wdt_dev, WDT_OPT_PAUSE_IN_SLEEP). With your experiment it does not set anything (bit mask set 0 -> setting nothing). This means that wdt for sleep will be set too 1 (default configuration) so we will reboot every-time we going to sleep.

    So back to my OP question. Why do the system reboot within 2-4h?

  • Can you please post a code snippet with the code you have tried?

  • requested code snippet:

        system_wdt_dev = device_get_binding(CONFIG_WDT_0_NAME);

        // Reset SoC when watchdog timer expires.
        wdt_config.flags = WDT_FLAG_RESET_SOC;

        // Expire watchdog after x milliseconds.
        wdt_config.window.min = SYSTEM_WDT_WINDOW_MIN;
        wdt_config.window.max = SYSTEM_WDT_WINDOW_MAX;

        // Set up watchdog callback. Jump into it when watchdog expired.
        wdt_config.callback = system_wdt_callback;

        wdt_channel_id = wdt_install_timeout(system_wdt_dev, &wdt_config);

        if (wdt_channel_id < 0) {

            return 1; // **** ERROR ****
        }

        if (wdt_setup(system_wdt_dev, 0) < 0) {

            return 1; // **** ERROR ****
        }

        return 0; // **** OK ****

  • Hi,

    Your code looks good.

    You set correct reset SOC flag - nRFs support only this mode.

    wdt_config.flags = WDT_FLAG_RESET_SOC;

    You set window.max value, I assume that your min value (SYSTEM_WDT_WINDOW_MIN) is zero. nRF hardware support basic situation when feed window is constant (starts at time 0 and expire in future - max).

    wdt_config.window.min = SYSTEM_WDT_WINDOW_MIN;
    wdt_config.window.max = SYSTEM_WDT_WINDOW_MAX;

    Callback is nice feature, but you have to be sure that you are doing things very quickly. You have two 32kHz cycles (http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fwdt.html&cp=2_1_0_39_2&anchor=concept_b4n_xzw_sr). The code is executing with 64MHz frequency (I assume situation without jumps/branches with flash wait states equals zero, clocks are synchronized - lucky we) so 1953 full CPU cycles, but in real situation less.

    You are calling setup function with 0 flag. In this case watchdog is kept running while the CPU is sleeping and is kept running when debugger is attached. 

    if (wdt_setup(system_wdt_dev, 0) < 0) {

    It is the place where I can see (eventually) potential problem. Maybe when watchdog is still running you miss the feed window in one/two/four hours. I can't confirm that. I just assume. You can connect logic analyzer to your GPIOs and try to trace situations (measure feed time etc) to check this.

    You can configure to pause watchdog while cpu is sleeping using flag previously recommended by Hakon. It is WDT_OPT_PAUSE_IN_SLEEP which set 1 at position zero. Watchdog driver checks if there is one at this position and set correct behaviour of the peripheral:

    https://github.com/zephyrproject-rtos/zephyr/blob/master/drivers/watchdog/wdt_nrfx.c#L42

    Please try options when watchdog is paused when CPU is sleeping:

    wdt_setup(system_wdt_dev, WDT_OPT_PAUSE_IN_SLEEP)

    I tried to find any errata entries about watchdog. There are two MCUs affected by WDT problems with increasing current consumption, but threre is no information about unexpected resets.

    So please try to setup watchdog with this option. If the problem will occurs after this change we try to prepare simple example together (extraction of affected code, based on zephyr and next one based on nrfx project to exclude influence of the zephyr RTOS) and pass it to Nordic engineers to look deply in peripheral's and CPU behaviour.

    Please tell me about your observations afterall. Thanks!

Related