summaryrefslogtreecommitdiff
path: root/bsp/k230/drivers/utest/test_wdt.c
blob: 026d4eb01629ec3f474259c2ca26eb5a2023a7a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * Copyright (c) 2006-2025, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * Refer to https://www.rt-thread.org/document/api/iwdg_sample_8c-example.html
 * This is a watchdog device test routine, the program searches for the watchdog
 * device by device name, then initializes the device and sets the watchdog
 * device overflow time.
 *
 * "test_wdt_feed" tests that the watchdog timer will not time out when the
 * watchdog is fed and will not cause the system to restart.
 *
 * "test_wdt_nofeed" tests that the watchdog timer will time out when the
 * watchdog is not fed and cause the system to restart.
 */

#include <rtthread.h>
#include <rtdevice.h>

#include "../interdrv/wdt/drv_wdt.h"
#include "utest.h"

/* Default watchdog device name */
/* If WDT0 and WDT1 both enabled, we use WDT0 */
#ifdef BSP_USING_WDT0
#define IWDG_DEVICE_NAME "wdt0"
#elif defined(BSP_USING_WDT1)
#define IWDG_DEVICE_NAME "wdt1"
#else
#error "No watchdog device defined!"
#endif

/* Watchdog device handle */
static rt_device_t wdg_dev;

/*
 * Dog feeding flag, 1 means feeding the dog, 0 means not feeding the dog.
 * This flag is used in the idle thread callback function.
 * If the dog is not fed, the system will restart due to watchdog timeout.
 */
static int flag_feed;

/* Overflow time, in seconds. */
static rt_uint32_t timeout = 3;

static void idle_hook(void)
{
    /* Feed the dog in the callback function of the idle thread */
    if (flag_feed)
        rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_KEEPALIVE, NULL);

    /* Do not print, otherwise the screen will display too much. */
}

static void waiting_for_timeout(int seconds)
{
    LOG_I("Waiting for watchdog timer time-out...\n");
    for (int i = 0; i < seconds; i++)
    {
        rt_thread_mdelay(1000);
        LOG_I(".");
    }
}

static void test_wdt_feed(void)
{
    rt_err_t ret = RT_EOK;

    /* Find the watchdog device according to the name and obtain the handle */
    wdg_dev = rt_device_find(IWDG_DEVICE_NAME);
    uassert_not_null(wdg_dev);

    /* Initialize the device */
    ret = rt_device_init(wdg_dev);
    uassert_int_equal(ret, RT_EOK);

    /* Set the watchdog timeout time */
    ret = rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
    uassert_int_equal(ret, RT_EOK);

    flag_feed = 1; /* Set feed the dog sign */

    /* start watchdog timer */
    rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_START, RT_NULL);
    LOG_I("Watchdog Timer [%s] is launched!\n", IWDG_DEVICE_NAME);

    /* Delay enough time to see if the system will be restarted by the watchdog */
    waiting_for_timeout(10);

    LOG_I("Thanks for feeding me, I'm still alive!\n");
    /* If you feed the dog successfully, you will have a chance to come here and close the gate dog. */
    rt_device_close(wdg_dev);
    LOG_I("Watchdog is closed!\n");

    LOG_I("Test Done with Feed!\n");

    return;
}

static void test_wdt_nofeed(void)
{
    rt_err_t ret = RT_EOK;

    /* Find the watchdog device according to the name and obtain the handle */
    wdg_dev = rt_device_find(IWDG_DEVICE_NAME);
    uassert_not_null(wdg_dev);

    /* Initialize the device */
    ret = rt_device_init(wdg_dev);
    uassert_int_equal(ret, RT_EOK);

    /* Set the watchdog timeout time */
    ret = rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
    uassert_int_equal(ret, RT_EOK);

    flag_feed = 0; /* Do not feed the dog */

    rt_device_control(wdg_dev, KD_DEVICE_CTRL_WDT_START, RT_NULL);
    LOG_I("Watchdog Timer [%s] is launched!\n", IWDG_DEVICE_NAME);

    /* Delay long enough and the system should reboot due to watchdog timeout. */
    LOG_I("Oops, I am so hungary and will be killed in seconds!\n");
    waiting_for_timeout(10);

    LOG_I("SHOULD NOT SEE THIS PRINT!\n");

    return;
}

static void test_wdt (void)
{
    UTEST_UNIT_RUN(test_wdt_feed);
    UTEST_UNIT_RUN(test_wdt_nofeed);
}

static rt_err_t utest_init(void)
{
    flag_feed = 0;
    rt_thread_idle_sethook(idle_hook);
    return RT_EOK;
}

UTEST_TC_EXPORT(test_wdt, "bsp.k230.drivers.wdt", utest_init, NULL, 10);