watchdog:test watchdog not depend on fs.

Signed-off-by: yangguangcai <yangguangcai@xiaomi.com>
This commit is contained in:
yangguangcai 2023-04-17 15:58:15 +08:00 committed by Xiang Xiao
parent 79e481d093
commit 76dff2b924
2 changed files with 48 additions and 88 deletions

View File

@ -55,6 +55,12 @@ ifneq ($(CONFIG_SIG_EVTHREAD),)
MAINSRC += drivertest_posix_timer.c MAINSRC += drivertest_posix_timer.c
PROGNAME += cmocka_posix_timer PROGNAME += cmocka_posix_timer
endif endif
ifneq ($(CONFIG_WATCHDOG),)
ifneq ($(CONFIG_BOARDCTL_RESET_CAUSE),)
MAINSRC += drivertest_watchdog.c
PROGNAME += cmocka_driver_watchdog
endif
endif endif
ifneq ($(CONFIG_PWM),) ifneq ($(CONFIG_PWM),)

View File

@ -46,16 +46,18 @@
#include <time.h> #include <time.h>
#include <nuttx/timers/watchdog.h> #include <nuttx/timers/watchdog.h>
#include <sys/boardctl.h>
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define WDG_DEFAULT_DEV_PATH "/dev/watchdog0" #define WDG_DEFAULT_DEV_PATH "/dev/watchdog0"
#define WDG_DEFAULT_INFO_PATH "/data/wdg_info"
#define WDG_DEFAULT_PINGTIMER 5000 #define WDG_DEFAULT_PINGTIMER 5000
#define WDG_DEFAULT_PINGDELAY 500 #define WDG_DEFAULT_PINGDELAY 500
#define WDG_DEFAULT_TIMEOUT 2000 #define WDG_DEFAULT_TIMEOUT 2000
#define WDG_DEFAULT_TESTCASE 0
#define WDG_COUNT_TESTCASE 4
#define OPTARG_TO_VALUE(value, type, base) \ #define OPTARG_TO_VALUE(value, type, base) \
do \ do \
@ -73,22 +75,13 @@
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
enum wdg_reset_cause_e
{
WDG_RESET_CAUSE_NONE,
WDG_RESET_CAUSE_NO_KEEP_ALIVE,
WDG_RESET_CAUSE_CRITICAL_SECTION_BUSY_LOOP,
WDG_RESET_CAUSE_IRQ_BUSY_LOOP
};
struct wdg_state_s struct wdg_state_s
{ {
char devpath[PATH_MAX]; char devpath[PATH_MAX];
char infopath[PATH_MAX];
uint32_t pingtime; uint32_t pingtime;
uint32_t pingdelay; uint32_t pingdelay;
uint32_t timeout; uint32_t timeout;
enum wdg_reset_cause_e reset_cause; int test_case;
}; };
/**************************************************************************** /****************************************************************************
@ -99,6 +92,8 @@ struct wdg_state_s
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
extern int board_reset_cause(FAR struct boardioc_reset_cause_s *cause);
/**************************************************************************** /****************************************************************************
* Name: get_timestamp * Name: get_timestamp
****************************************************************************/ ****************************************************************************/
@ -135,52 +130,6 @@ static uint32_t get_time_elaps(uint32_t prev_tick)
return prev_tick; return prev_tick;
} }
/****************************************************************************
* Name: wdg_write_reset_cause
****************************************************************************/
static void wdg_write_reset_cause(FAR struct wdg_state_s *state)
{
int fd;
int ret;
ssize_t size;
fd = open(state->infopath, O_WRONLY | O_CREAT, 0666);
assert_true(fd > 0);
size = write(fd, &state->reset_cause, sizeof(state->reset_cause));
assert_int_equal(size, sizeof(state->reset_cause));
ret = fsync(fd);
assert_return_code(ret, OK);
ret = close(fd);
assert_return_code(ret, OK);
}
/****************************************************************************
* Name: wdg_read_reset_cause
****************************************************************************/
static void wdg_read_reset_cause(FAR struct wdg_state_s *state)
{
int fd;
int ret;
ssize_t size;
fd = open(state->infopath, O_RDONLY);
if (fd < 0)
{
state->reset_cause = WDG_RESET_CAUSE_NONE;
return;
}
size = read(fd, &state->reset_cause, sizeof(state->reset_cause));
assert_int_equal(size, sizeof(state->reset_cause));
ret = close(fd);
assert_return_code(ret, OK);
}
/**************************************************************************** /****************************************************************************
* Name: wdg_init * Name: wdg_init
****************************************************************************/ ****************************************************************************/
@ -215,14 +164,14 @@ static int wdg_init(FAR struct wdg_state_s *state)
static void show_usage(FAR const char *progname, static void show_usage(FAR const char *progname,
FAR struct wdg_state_s *wdg_state, int exitcode) FAR struct wdg_state_s *wdg_state, int exitcode)
{ {
printf("Usage: %s -d <devpath> -p <infopath> -t <pingtime>" printf("Usage: %s -d <devpath> -r <test case> -t <pingtime>"
"-l <pingdelay> -o <timeout>\n", progname); "-l <pingdelay> -o <timeout>\n", progname);
printf(" [-d devpath] selects the WATCHDOG device.\n" printf(" [-d devpath] selects the WATCHDOG device.\n"
" Default: %s Current: %s\n", WDG_DEFAULT_DEV_PATH, " Default: %s Current: %s\n", WDG_DEFAULT_DEV_PATH,
wdg_state->devpath); wdg_state->devpath);
printf(" [-p infopath] selects the WATCHDOG reset cause path.\n" printf(" [-r test_case] selects the testcase.\n"
" Default: %s Current: %s\n", WDG_DEFAULT_INFO_PATH, " Default: %d Current: %d\n", WDG_DEFAULT_TESTCASE,
wdg_state->infopath); wdg_state->test_case);
printf(" [-t pingtime] Selects the <delay> time in milliseconds.\n" printf(" [-t pingtime] Selects the <delay> time in milliseconds.\n"
" Default: %d Current: %" PRIu32 "\n", " Default: %d Current: %" PRIu32 "\n",
WDG_DEFAULT_PINGTIMER, wdg_state->pingtime); WDG_DEFAULT_PINGTIMER, wdg_state->pingtime);
@ -247,7 +196,7 @@ static void parse_commandline(FAR struct wdg_state_s *wdg_state, int argc,
int ch; int ch;
int converted; int converted;
while ((ch = getopt(argc, argv, "d:p:t:l:o:h")) != ERROR) while ((ch = getopt(argc, argv, "d:r:t:l:o:h")) != ERROR)
{ {
switch (ch) switch (ch)
{ {
@ -258,6 +207,16 @@ static void parse_commandline(FAR struct wdg_state_s *wdg_state, int argc,
case 'p': case 'p':
strlcpy(wdg_state->infopath, optarg, strlcpy(wdg_state->infopath, optarg,
sizeof(wdg_state->infopath)); sizeof(wdg_state->infopath));
case 'r':
OPTARG_TO_VALUE(converted, uint32_t, 10);
if (converted < WDG_DEFAULT_TESTCASE ||
converted >= WDG_COUNT_TESTCASE)
{
printf("signal out of range: %d\n", converted);
show_usage(argv[0], wdg_state, EXIT_FAILURE);
}
wdg_state->test_case = converted;
break; break;
case 't': case 't':
@ -315,18 +274,20 @@ static void test_case_wdog_01(FAR void **state)
int ret; int ret;
uint32_t start_ms; uint32_t start_ms;
FAR struct wdg_state_s *wdg_state; FAR struct wdg_state_s *wdg_state;
struct boardioc_reset_cause_s reset_cause;
wdg_state = (FAR struct wdg_state_s *)*state; wdg_state = (FAR struct wdg_state_s *)*state;
wdg_read_reset_cause(wdg_state);
/* If it's not the first step, skip... */ /* If it's not the first step, skip... */
if (wdg_state->reset_cause != WDG_RESET_CAUSE_NONE) if (wdg_state->test_case != 0)
{ {
return; return;
} }
board_reset_cause(&reset_cause);
assert_int_equal(reset_cause.cause, BOARDIOC_RESETCAUSE_SYS_CHIPPOR);
dev_fd = wdg_init(wdg_state); dev_fd = wdg_init(wdg_state);
/* Get the starting time */ /* Get the starting time */
@ -347,11 +308,6 @@ static void test_case_wdog_01(FAR void **state)
assert_return_code(ret, OK); assert_return_code(ret, OK);
} }
/* write the reset cause */
wdg_state->reset_cause = WDG_RESET_CAUSE_NO_KEEP_ALIVE;
wdg_write_reset_cause(wdg_state);
/* Then stop pinging */ /* Then stop pinging */
/* Sleep for the requested amount of time */ /* Sleep for the requested amount of time */
@ -372,20 +328,19 @@ static void test_case_wdog_01(FAR void **state)
static void test_case_wdog_02(FAR void **state) static void test_case_wdog_02(FAR void **state)
{ {
FAR struct wdg_state_s *wdg_state; FAR struct wdg_state_s *wdg_state;
struct boardioc_reset_cause_s reset_cause;
wdg_state = (FAR struct wdg_state_s *)*state; wdg_state = (FAR struct wdg_state_s *)*state;
wdg_read_reset_cause(wdg_state); if (wdg_state->test_case != 1)
if (wdg_state->reset_cause != WDG_RESET_CAUSE_NO_KEEP_ALIVE)
{ {
return; return;
} }
wdg_init(wdg_state); board_reset_cause(&reset_cause);
assert_int_equal(reset_cause.cause, BOARDIOC_RESETCAUSE_SYS_RWDT);
wdg_state->reset_cause = WDG_RESET_CAUSE_CRITICAL_SECTION_BUSY_LOOP; wdg_init(wdg_state);
wdg_write_reset_cause(wdg_state);
enter_critical_section(); enter_critical_section();
@ -418,20 +373,19 @@ static void test_case_wdog_03(FAR void **state)
int ret; int ret;
static struct wdog_s wdog; static struct wdog_s wdog;
FAR struct wdg_state_s *wdg_state; FAR struct wdg_state_s *wdg_state;
struct boardioc_reset_cause_s reset_cause;
wdg_state = (FAR struct wdg_state_s *)*state; wdg_state = (FAR struct wdg_state_s *)*state;
wdg_read_reset_cause(wdg_state); if (wdg_state->test_case != 2)
if (wdg_state->reset_cause != WDG_RESET_CAUSE_CRITICAL_SECTION_BUSY_LOOP)
{ {
return; return;
} }
wdg_init(wdg_state); board_reset_cause(&reset_cause);
assert_int_equal(reset_cause.cause, BOARDIOC_RESETCAUSE_SYS_RWDT);
wdg_state->reset_cause = WDG_RESET_CAUSE_IRQ_BUSY_LOOP; wdg_init(wdg_state);
wdg_write_reset_cause(wdg_state);
ret = wd_start(&wdog, 1, wdg_wdentry, (wdparm_t)0); ret = wd_start(&wdog, 1, wdg_wdentry, (wdparm_t)0);
assert_return_code(ret, OK); assert_return_code(ret, OK);
@ -457,14 +411,14 @@ static void test_case_wdog_04(FAR void **state)
int ret; int ret;
uint32_t start_ms; uint32_t start_ms;
FAR struct wdg_state_s *wdg_state; FAR struct wdg_state_s *wdg_state;
struct boardioc_reset_cause_s reset_cause;
wdg_state = (FAR struct wdg_state_s *)*state; wdg_state = (FAR struct wdg_state_s *)*state;
wdg_read_reset_cause(wdg_state); assert_int_equal(wdg_state->test_case, 3);
assert_int_equal(wdg_state->reset_cause, WDG_RESET_CAUSE_IRQ_BUSY_LOOP);
ret = remove(wdg_state->infopath); board_reset_cause(&reset_cause);
assert_return_code(ret, OK); assert_int_equal(reset_cause.cause, BOARDIOC_RESETCAUSE_SYS_RWDT);
dev_fd = wdg_init(wdg_state); dev_fd = wdg_init(wdg_state);
@ -508,10 +462,10 @@ int main(int argc, FAR char *argv[])
struct wdg_state_s wdg_state = struct wdg_state_s wdg_state =
{ {
.devpath = WDG_DEFAULT_DEV_PATH, .devpath = WDG_DEFAULT_DEV_PATH,
.infopath = WDG_DEFAULT_INFO_PATH,
.pingtime = WDG_DEFAULT_PINGTIMER, .pingtime = WDG_DEFAULT_PINGTIMER,
.pingdelay = WDG_DEFAULT_PINGDELAY, .pingdelay = WDG_DEFAULT_PINGDELAY,
.timeout = WDG_DEFAULT_TIMEOUT .timeout = WDG_DEFAULT_TIMEOUT,
.test_case = WDG_DEFAULT_TESTCASE
}; };
parse_commandline(&wdg_state, argc, argv); parse_commandline(&wdg_state, argc, argv);