1 /*
2  * Copyright (c) 2006-2025, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * Refer to https://www.rt-thread.org/document/api/iwdg_sample_8c-example.html
9  * This is a watchdog device test routine, the program searches for the watchdog
10  * device by device name, then initializes the device and sets the watchdog
11  * device overflow time.
12  *
13  * "test_wdt_feed" tests that the watchdog timer will not time out when the
14  * watchdog is fed and will not cause the system to restart.
15  *
16  * "test_wdt_nofeed" tests that the watchdog timer will time out when the
17  * watchdog is not fed and cause the system to restart.
18  */
19 
20 #include <rtthread.h>
21 #include <rtdevice.h>
22 
23 #include "../interdrv/wdt/drv_wdt.h"
24 #include "utest.h"
25 
26 /* Default watchdog device name */
27 /* If WDT0 and WDT1 both enabled, we use WDT0 */
28 #ifdef BSP_USING_WDT0
29 #define IWDG_DEVICE_NAME "wdt0"
30 #elif defined(BSP_USING_WDT1)
31 #define IWDG_DEVICE_NAME "wdt1"
32 #else
33 #error "No watchdog device defined!"
34 #endif
35 
36 /* Watchdog device handle */
37 static rt_device_t wdg_dev;
38 
39 /*
40  * Dog feeding flag, 1 means feeding the dog, 0 means not feeding the dog.
41  * This flag is used in the idle thread callback function.
42  * If the dog is not fed, the system will restart due to watchdog timeout.
43  */
44 static int flag_feed;
45 
46 /* Overflow time, in seconds. */
47 static rt_uint32_t timeout = 3;
48 
idle_hook(void)49 static void idle_hook(void)
50 {
51     /* Feed the dog in the callback function of the idle thread */
52     if (flag_feed)
53         rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
54 
55     /* Do not print, otherwise the screen will display too much. */
56 }
57 
waiting_for_timeout(int seconds)58 static void waiting_for_timeout(int seconds)
59 {
60     LOG_I("Waiting for watchdog timer time-out...\n");
61     for (int i = 0; i < seconds; i++)
62     {
63         rt_thread_mdelay(1000);
64         LOG_I(".");
65     }
66 }
67 
test_wdt_feed(void)68 static void test_wdt_feed(void)
69 {
70     rt_err_t ret = RT_EOK;
71 
72     /* Find the watchdog device according to the name and obtain the handle */
73     wdg_dev = rt_device_find(IWDG_DEVICE_NAME);
74     uassert_not_null(wdg_dev);
75 
76     /* Initialize the device */
77     ret = rt_device_init(wdg_dev);
78     uassert_int_equal(ret, RT_EOK);
79 
80     /* Set the watchdog timeout time */
81     ret = rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
82     uassert_int_equal(ret, RT_EOK);
83 
84     flag_feed = 1; /* Set feed the dog sign */
85 
86     /* start watchdog timer */
87     rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_START, RT_NULL);
88     LOG_I("Watchdog Timer [%s] is launched!\n", IWDG_DEVICE_NAME);
89 
90     /* Delay enough time to see if the system will be restarted by the watchdog */
91     waiting_for_timeout(10);
92 
93     LOG_I("Thanks for feeding me, I'm still alive!\n");
94     /* If you feed the dog successfully, you will have a chance to come here and close the gate dog. */
95     rt_device_close(wdg_dev);
96     LOG_I("Watchdog is closed!\n");
97 
98     LOG_I("Test Done with Feed!\n");
99 
100     return;
101 }
102 
test_wdt_nofeed(void)103 static void test_wdt_nofeed(void)
104 {
105     rt_err_t ret = RT_EOK;
106 
107     /* Find the watchdog device according to the name and obtain the handle */
108     wdg_dev = rt_device_find(IWDG_DEVICE_NAME);
109     uassert_not_null(wdg_dev);
110 
111     /* Initialize the device */
112     ret = rt_device_init(wdg_dev);
113     uassert_int_equal(ret, RT_EOK);
114 
115     /* Set the watchdog timeout time */
116     ret = rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
117     uassert_int_equal(ret, RT_EOK);
118 
119     flag_feed = 0; /* Do not feed the dog */
120 
121     rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_START, RT_NULL);
122     LOG_I("Watchdog Timer [%s] is launched!\n", IWDG_DEVICE_NAME);
123 
124     /* Delay long enough and the system should reboot due to watchdog timeout. */
125     LOG_I("Oops, I am so hungary and will be killed in seconds!\n");
126     waiting_for_timeout(10);
127 
128     LOG_I("SHOULD NOT SEE THIS PRINT!\n");
129 
130     return;
131 }
132 
test_wdt(void)133 static void test_wdt (void)
134 {
135     UTEST_UNIT_RUN(test_wdt_feed);
136     UTEST_UNIT_RUN(test_wdt_nofeed);
137 }
138 
utest_init(void)139 static rt_err_t utest_init(void)
140 {
141     flag_feed = 0;
142     rt_thread_idle_sethook(idle_hook);
143     return RT_EOK;
144 }
145 
146 UTEST_TC_EXPORT(test_wdt, "wdt", utest_init, NULL, 10);