zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.67k stars 6.52k forks source link

stm32 iwdt wdt_install_timeout not working properly #53935

Closed wojciechslenska closed 1 year ago

wojciechslenska commented 1 year ago

In the new zephyr version, there is a regression in iwdt driver.

code example

Following code set wdt time to 32s and feed is each 20s

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);

int main(void)
{
    const struct device* wdt = DEVICE_DT_GET(DT_NODELABEL(iwdg));
    struct wdt_timeout_cfg wdt_config = { .window = {.min = 0U, .max = 32000U}, .flags = WDT_FLAG_RESET_SOC, .callback = NULL};

    if (wdt_install_timeout(wdt, &wdt_config) != 0) {
        LOG_ERR("Watchdog install error!");
    }

    if (wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG) != 0) {
        LOG_ERR("Watchdog setup error");
    }

    while(1){
        for(int i=0;i<4;i++){
            LOG_INF("tick");
            k_sleep(K_MSEC(5000));
        }
        LOG_INF("feed");
        wdt_feed(wdt, 0);
    }
    return 0;
}

and config

CONFIG_WATCHDOG=y
CONFIG_IWDG_STM32_INITIAL_TIMEOUT=10000

wrong behavior

In the current zephyr, system goes to bootloop, the output is:

*** Booting Zephyr OS build zephyr-v3.2.0-3690-g227226313a87 ***
[00:00:00.000,000] <inf> app: tick
[00:00:05.000,000] <inf> app: tick
[00:00:10.000,000] <inf> app: tick
[00:00:15.000,000] <inf> app: tick
uart:~$ 

*** Booting Zephyr OS build zephyr-v3.2.0-3690-g227226313a87 ***
[00:00:00.000,000] <inf> app: tick
[00:00:05.000,000] <inf> app: tick
[00:00:10.000,000] <inf> app: tick
[00:00:15.000,000] <inf> app: tick
uart:~$ 

proper behavior

When I revert the following change: 9400de333e88f8a9c835764102544809646c837b Works properly and the output is:

*** Booting Zephyr OS build zephyr-v3.2.0-3691-g69d8bc71e63b ***
[00:00:00.000,000] <inf> app: tick
[00:00:05.000,000] <inf> app: tick
[00:00:10.001,000] <inf> app: tick
[00:00:15.001,000] <inf> app: tick
[00:00:20.001,000] <inf> app: feed
[00:00:20.001,000] <inf> app: tick
[00:00:25.001,000] <inf> app: tick
[00:00:30.001,000] <inf> app: tick
[00:00:35.001,000] <inf> app: tick
[00:00:40.001,000] <inf> app: feed
[00:00:40.001,000] <inf> app: tick

Environment:

FRASTM commented 1 year ago

The commit was introduced by the https://github.com/zephyrproject-rtos/zephyr/pull/53690 Instead of reverting, a proposal could be to follow the sequence as described in the refMan

1. Enable the IWDG by writing 0x0000 CCCC in the IWDG key register (IWDG_KR).
2. Enable register access by writing 0x0000 5555 in the IWDG key register (IWDG_KR).
3. Write the prescaler by programming the IWDG prescaler register (IWDG_PR).
4. Write the IWDG reload register (IWDG_RLR).
5. If needed, enable the early wakeup interrupt, and program the early wakeup
comparator, by writing the proper values into the IWDG early wakeup interrupt register
(IWDG_EWCR).
6. Wait for the registers to be updated (IWDG_SR = 0x0000 0000).
7. Refresh the counter with RL[11:0] value, and write-pro
write iwdg register  during the setup and just calculating the values during the install_timeout

With variables containing the prescaler and reload counter, the install_timeout() will calculate the values then the setup() will enable and wrtie the iwdg resgister.