Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion components/drivers/watchdog/SConscript
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from building import *
import os

group = []

if not GetDepend(['RT_USING_WDT']):
Return('group')

cwd = GetCurrentDir()
list = os.listdir(cwd)
CPPPATH = [cwd + '/../include']

src = ['dev_watchdog.c']
Expand All @@ -19,4 +19,9 @@ if GetDepend(['RT_WDT_I6300ESB']):

group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)

list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))

Return('group')
37 changes: 37 additions & 0 deletions components/drivers/watchdog/utest/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
menu "Watchdog Test"
depends on RT_USING_WDT

config RT_UTEST_WDT
bool "Watchdog Smoke Test"
default n
help
Validate watchdog device find/open and timeout set/get. Optional
start/keepalive/stop is off by default to avoid board reset when the
hardware cannot stop the WDT.

if RT_UTEST_WDT

config RT_UTEST_WDT_DEVICE_NAME
string "Watchdog Device Name"
default "wdt"
help
Device name registered by the BSP, usually "wdt".

config RT_UTEST_WDT_TIMEOUT_SEC
int "Timeout Used by Smoke Test (Seconds)"
range 1 60
default 5
help
Timeout value written by SET_TIMEOUT and checked by GET_TIMEOUT.

config RT_UTEST_WDT_START
bool "Also Start/Keepalive/Stop Watchdog"
default n
help
When enabled, the test starts the WDT with the configured timeout,
feeds it once, then stops it. Keep this off unless the BSP WDT can
be stopped safely; otherwise the board may reset if STOP fails.

endif

endmenu
13 changes: 13 additions & 0 deletions components/drivers/watchdog/utest/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Import('rtconfig')
from building import *

cwd = GetCurrentDir()
src = []
CPPPATH = [cwd, cwd + '/../../include']

if GetDepend(['RT_UTEST_WDT']):
src += ['wdt_tc.c']

group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES', 'RT_USING_WDT'], CPPPATH = CPPPATH)

Return('group')
179 changes: 179 additions & 0 deletions components/drivers/watchdog/utest/wdt_tc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* Copyright (c) 2006-2026 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-10-17 seteiro add watchdog smoke utest for #11446
*/

/**
* Test Case Name: Watchdog Smoke Test
*
* Test Objectives:
* - Verify that the watchdog device can be found and opened.
* - Verify SET_TIMEOUT / GET_TIMEOUT round-trip.
* - Optionally verify START / KEEPALIVE / STOP when enabled.
*
* Dependencies:
* - Requires `RT_UTEST_WDT` and `RT_USING_WDT`.
* - BSP must register a watchdog device (default name `wdt`).
* - START path is optional (`RT_UTEST_WDT_START`); leave it off when the
* hardware cannot stop the WDT, otherwise the board may reset.
*
* Expected Results:
* - Find/open and timeout set/get checks pass.
* - When START is enabled, start/keepalive/stop also pass.
*
* Board notes:
* - qemu-vexpress-a9 enables `RT_USING_WDT` but does not register a WDT
* device; enable this case on a BSP that provides `wdt` (e.g. CH32/STM32).
*/

#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/dev_watchdog.h>
#include "utest.h"

#ifdef RT_UTEST_WDT

#ifndef RT_UTEST_WDT_DEVICE_NAME
#define RT_UTEST_WDT_DEVICE_NAME "wdt"
#endif

#ifndef RT_UTEST_WDT_TIMEOUT_SEC
#define RT_UTEST_WDT_TIMEOUT_SEC 5
#endif

#define WDT_TC_SUITE_TIMEOUT 10

static rt_device_t wdt_tc_device;
static rt_bool_t wdt_tc_device_opened;

static void wdt_timeout_set_get_test(void)
{
rt_err_t result;
rt_uint32_t timeout;
rt_uint32_t readback;

timeout = RT_UTEST_WDT_TIMEOUT_SEC;
result = rt_device_control(wdt_tc_device, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
uassert_int_equal(result, RT_EOK);
if (result != RT_EOK)
{
return;
}

readback = 0;
result = rt_device_control(wdt_tc_device, RT_DEVICE_CTRL_WDT_GET_TIMEOUT, &readback);
if (result == -RT_ENOSYS)
{
LOG_W("GET_TIMEOUT not supported, skip readback check");
return;
}

uassert_int_equal(result, RT_EOK);
if (result != RT_EOK)
{
return;
}

LOG_I("WDT timeout set=%u get=%u", (unsigned)timeout, (unsigned)readback);
uassert_int_equal(readback, timeout);
}

#ifdef RT_UTEST_WDT_START
static void wdt_start_keepalive_stop_test(void)
{
rt_err_t result;
rt_uint32_t timeout;

timeout = RT_UTEST_WDT_TIMEOUT_SEC;
result = rt_device_control(wdt_tc_device, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
uassert_int_equal(result, RT_EOK);
if (result != RT_EOK)
{
return;
}

result = rt_device_control(wdt_tc_device, RT_DEVICE_CTRL_WDT_START, RT_NULL);
uassert_int_equal(result, RT_EOK);
if (result != RT_EOK)
{
return;
}

result = rt_device_control(wdt_tc_device, RT_DEVICE_CTRL_WDT_KEEPALIVE, RT_NULL);
uassert_int_equal(result, RT_EOK);

result = rt_device_control(wdt_tc_device, RT_DEVICE_CTRL_WDT_STOP, RT_NULL);
uassert_int_equal(result, RT_EOK);
if (result != RT_EOK)
{
LOG_E("WDT STOP failed; board may reset when timeout expires");
}
}
#endif /* RT_UTEST_WDT_START */

static rt_err_t utest_tc_init(void)
{
rt_err_t result;
rt_device_t wdt_device;

wdt_tc_device = RT_NULL;
wdt_tc_device_opened = RT_FALSE;

wdt_device = rt_device_find(RT_UTEST_WDT_DEVICE_NAME);
if (wdt_device == RT_NULL)
{
LOG_E("Watchdog device %s is not registered", RT_UTEST_WDT_DEVICE_NAME);
return -RT_ERROR;
}
if (wdt_device->type != RT_Device_Class_WDT)
{
LOG_E("Device %s is not a watchdog device", RT_UTEST_WDT_DEVICE_NAME);
return -RT_ERROR;
}

result = rt_device_open(wdt_device, RT_DEVICE_OFLAG_RDWR);
if (result != RT_EOK)
{
return result;
}

wdt_tc_device = wdt_device;
wdt_tc_device_opened = RT_TRUE;
return RT_EOK;
}

static rt_err_t utest_tc_cleanup(void)
{
rt_err_t result;

result = RT_EOK;
if (wdt_tc_device_opened)
{
result = rt_device_close(wdt_tc_device);
wdt_tc_device = RT_NULL;
wdt_tc_device_opened = RT_FALSE;
}

return result;
}

static void testcase(void)
{
UTEST_UNIT_RUN(wdt_timeout_set_get_test);
#ifdef RT_UTEST_WDT_START
UTEST_UNIT_RUN(wdt_start_keepalive_stop_test);
#endif
}

UTEST_TC_EXPORT(testcase,
"components.drivers.watchdog.smoke",
utest_tc_init,
utest_tc_cleanup,
WDT_TC_SUITE_TIMEOUT);

#endif /* RT_UTEST_WDT */
1 change: 1 addition & 0 deletions components/utilities/utest/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ menu "RT-Thread Utestcases"
rsource "../../../components/drivers/serial/utest/Kconfig"
rsource "../../../components/drivers/smp_call/utest/Kconfig"
rsource "../../../components/drivers/spi/utest/Kconfig"
rsource "../../../components/drivers/watchdog/utest/Kconfig"
endmenu

rsource "../../../components/dfs/utest/Kconfig"
Expand Down
Loading