1 /*
2  * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024-12-30     CDT          first version
9  */
10 
11 /*
12  * 程序清单:这是 WDT 设备使用例程
13  * 例程导出了 wdt_sample 命令到控制终端。
14  * 命令调用格式:wdt_sample set_timeout x
15  * 命令解释:x 对应的是超时时间,以实际计算的接近值为准
16  * 终端先打印N次设置的超时,然后依次递减等待N秒后复位系统(N等于设置的超时秒数)
17  */
18 
19 #include <rtthread.h>
20 #include <rtdevice.h>
21 #include <stdlib.h>
22 
23 #ifdef BSP_USING_WDT_TMR
24 
25 #if defined(BSP_USING_WDT)
26     #define WDT_DEVICE_NAME     "wdt"
27 #elif defined(BSP_USING_SWDT)
28     #define WDT_DEVICE_NAME     "swdt"
29 #endif
30 
31 static rt_device_t wdg_dev;
32 static rt_uint32_t valid_timeout = 0;
33 static rt_uint32_t wdt_cnt = 0;
34 
idle_hook(void)35 static void idle_hook(void)
36 {
37     if (wdt_cnt < valid_timeout)
38     {
39         /* Feed watch dog */
40         rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
41     }
42 }
43 
_wdt_cmd_print_usage(void)44 static void _wdt_cmd_print_usage(void)
45 {
46     rt_kprintf("wdt_sample [option]\n");
47     rt_kprintf("  set_timeout: set wdt timeout(S)\n");
48     rt_kprintf("    e.g. MSH >wdt_sample set_timeout 10\n");
49 }
50 
wdt_sample(int argc,char * argv[])51 static int wdt_sample(int argc, char *argv[])
52 {
53     rt_err_t ret = RT_EOK;
54     rt_uint32_t timeleft;
55     rt_uint32_t timeout = atoi(argv[2]);
56 
57     if (argc != 3)
58     {
59         _wdt_cmd_print_usage();
60         return -RT_ERROR;
61     }
62 
63     if (!rt_strcmp("set_timeout", argv[1]))
64     {
65         wdg_dev = rt_device_find(WDT_DEVICE_NAME);
66         if (!wdg_dev)
67         {
68             rt_kprintf("find %s failed!\n", WDT_DEVICE_NAME);
69             return -RT_ERROR;
70         }
71 
72         ret = rt_device_init(wdg_dev);
73         if (ret != RT_EOK)
74         {
75             rt_kprintf("init %s failed!\n", WDT_DEVICE_NAME);
76             return -RT_ERROR;
77         }
78 
79         /* Set timeout (Unit:S) */
80         ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
81         if (ret != RT_EOK)
82         {
83             rt_kprintf("set %s timeout failed!\n", WDT_DEVICE_NAME);
84             return -RT_ERROR;
85         }
86 
87         /* Get the time when it real effective */
88         ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_GET_TIMEOUT, &valid_timeout);
89         if (ret != RT_EOK)
90         {
91             rt_kprintf("start %s failed!\n", WDT_DEVICE_NAME);
92             return -RT_ERROR;
93         }
94         rt_kprintf("valid_timeout = %d S\n", valid_timeout);
95 
96         /* Start WDT */
97         ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
98         if (ret != RT_EOK)
99         {
100             rt_kprintf("start %s failed!\n", WDT_DEVICE_NAME);
101             return -RT_ERROR;
102         }
103 
104         rt_thread_idle_sethook(idle_hook);
105 
106         for (;;)
107         {
108             rt_thread_mdelay(1000);
109             rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_GET_TIMELEFT, &timeleft);
110             rt_kprintf("timeleft = %d S\n", timeleft);
111             wdt_cnt++;
112         }
113     }
114     else
115     {
116         _wdt_cmd_print_usage();
117         return -RT_ERROR;
118     }
119 
120     return ret;
121 }
122 
123 MSH_CMD_EXPORT(wdt_sample, wdt_sample [option]);
124 
125 #endif
126