This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit b01765c57d33ea1a7c9abfa9736cd9f18f511713 Author: ouyangxiangzhen <[email protected]> AuthorDate: Tue Jul 30 12:13:04 2024 +0800 testing/ostest: Add recursive watchdog callback testcase This patch added wdog recursive test cases. Signed-off-by: ouyangxiangzhen <[email protected]> Signed-off-by: ligd <[email protected]> --- testing/ostest/wdog.c | 138 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 110 insertions(+), 28 deletions(-) diff --git a/testing/ostest/wdog.c b/testing/ostest/wdog.c index 65a3d2a1d..1e44d1cae 100644 --- a/testing/ostest/wdog.c +++ b/testing/ostest/wdog.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include <nuttx/config.h> +#include <nuttx/arch.h> #include <nuttx/wdog.h> #include <pthread.h> @@ -34,12 +35,15 @@ * Pre-processor Definitions ****************************************************************************/ -#define WDOGTEST_RAND_ITER 1024 -#define WDOGTEST_THREAD_NR 8 +#define WDOGTEST_RAND_ITER 1024 +#define WDOGTEST_THREAD_NR 8 +#define WDOGTEST_TOLERENT_LATENCY_US 5000 -#define wdtest_assert(x) _ASSERT(x, __ASSERT_FILE__, __ASSERT_LINE__) +#define wdtest_assert(x) _ASSERT(x, __FILE__, __LINE__) -#define wdtest_printf(...) printf(__VA_ARGS__) +#define wdtest_printf(...) printf(__VA_ARGS__) + +#define wdtest_delay(delay_us) usleep(delay_us) /**************************************************************************** * Private Type @@ -47,8 +51,10 @@ typedef struct wdtest_param_s { - uint64_t callback_cnt; - clock_t triggered_tick; + FAR struct wdog_s *wdog; + sclock_t interval; + uint64_t callback_cnt; + clock_t triggered_tick; } wdtest_param_t; /**************************************************************************** @@ -68,45 +74,59 @@ static void wdtest_callback(wdparm_t param) } static void wdtest_once(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, - sclock_t delay_ns) + sclock_t delay_us) { uint64_t cnt; - long diff; + long long diff; clock_t wdset_tick; struct timespec tp; + clock_t delay_ticks = USEC2TICK((clock_t)delay_us); + + wdtest_printf("wdtest_once %lld us\n", (long long)delay_us); clock_gettime(CLOCK_MONOTONIC, &tp); wdset_tick = clock_time2ticks(&tp); cnt = param->callback_cnt; - wdtest_assert(wd_start(wdog, NSEC2TICK((clock_t)delay_ns), wdtest_callback, + wdtest_assert(wd_start(wdog, delay_ticks, wdtest_callback, (wdparm_t)param) == OK); - usleep(delay_ns / 1000 + 1); - diff = (long)(param->triggered_tick - wdset_tick); - wdtest_printf("wd_start with delay %ld ns, diff ticks %ld\n", - (long)delay_ns, diff); - wdtest_assert(cnt + 1 == param->callback_cnt); + + while (cnt + 1 != param->callback_cnt) + { + wdtest_delay(delay_us); + } + + diff = (long long)(param->triggered_tick - wdset_tick); + + /* Ensure diff - delay_ticks is within the tolerance limit. */ + + wdtest_assert(diff - delay_ticks >= 0); + wdtest_assert(diff - delay_ticks < + USEC2TICK(WDOGTEST_TOLERENT_LATENCY_US) + 1); + wdtest_printf("wdtest_once latency ticks %lld\n", diff - delay_ticks); } static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, - sclock_t rand_ns) + sclock_t rand_us) { int idx; - sclock_t delay_ns; + sclock_t delay_us; uint64_t cnt = param->callback_cnt; for (idx = 0; idx < WDOGTEST_RAND_ITER; idx++) { - delay_ns = rand() % rand_ns; - wdtest_assert(wd_start(wdog, NSEC2TICK(delay_ns), wdtest_callback, + delay_us = rand() % rand_us; + wdtest_assert(wd_start(wdog, USEC2TICK(delay_us), wdtest_callback, (wdparm_t)param) == 0); /* Wait or Cancel 50/50 */ - if (delay_ns % 2) + if (delay_us % 2) { - usleep((delay_ns / 1000) + 1); - wdtest_assert(cnt + 1 == param->callback_cnt); + while (cnt + 1 != param->callback_cnt) + { + wdtest_delay(delay_us); + } } else { @@ -117,6 +137,56 @@ static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param, } } +static void wdtest_callback_recursive(wdparm_t param) +{ + struct timespec tp; + FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param; + sclock_t interval = wdtest_param->interval; + + wd_start(wdtest_param->wdog, interval, + wdtest_callback_recursive, param); + + clock_gettime(CLOCK_MONOTONIC, &tp); + + wdtest_param->callback_cnt += 1; + wdtest_param->triggered_tick = clock_time2ticks(&tp); +} + +static void wdtest_recursive(FAR struct wdog_s *wdog, + FAR wdtest_param_t *param, + sclock_t delay_us, + unsigned int times) +{ + uint64_t cnt; + struct timespec tp; + clock_t wdset_tick; + + wdtest_printf("wdtest_recursive %lldus\n", (long long)delay_us); + cnt = param->callback_cnt; + param->wdog = wdog; + param->interval = (sclock_t)USEC2TICK((clock_t)delay_us); + + wdtest_assert(param->interval >= 0); + + clock_gettime(CLOCK_MONOTONIC, &tp); + wdset_tick = clock_time2ticks(&tp); + + wdtest_assert(wd_start(param->wdog, param->interval, + wdtest_callback_recursive, + (wdparm_t)param) == OK); + + while (param->callback_cnt < cnt + times) + { + wdtest_delay(delay_us); + } + + wdtest_assert(wd_cancel(param->wdog) == 0); + + wdtest_printf("recursive wdog triggered %u times, elapsed tick %lld\n", + times, + (long long)(param->triggered_tick - wdset_tick)); +} + static void wdog_test_run(FAR wdtest_param_t *param) { uint64_t cnt; @@ -145,14 +215,16 @@ static void wdog_test_run(FAR wdtest_param_t *param) /* Delay > 0, small */ wdtest_once(&test_wdog, param, 1); + wdtest_once(&test_wdog, param, 10); + wdtest_once(&test_wdog, param, 100); + wdtest_once(&test_wdog, param, 1000); + wdtest_once(&test_wdog, param, 10000); + wdtest_delay(10); /* Delay > 0, middle 100us */ wdtest_once(&test_wdog, param, 100000); - - /* Delay > 0, large ~123456us */ - - wdtest_once(&test_wdog, param, 123456789); + wdtest_once(&test_wdog, param, 1000000); /* Delay > 0, maximum */ @@ -166,7 +238,7 @@ static void wdog_test_run(FAR wdtest_param_t *param) /* Sleep for 1s */ - usleep(USEC_PER_SEC); + wdtest_delay(USEC_PER_SEC); /* Testing wd_gettime */ @@ -192,11 +264,21 @@ static void wdog_test_run(FAR wdtest_param_t *param) wdtest_callback, (wdparm_t)param) != OK); wdtest_assert(wd_gettime(&test_wdog) == 0); - /* Random delay ~1024us */ + /* Recursive wdog delay from 10us to 1000us */ + + wdtest_recursive(&test_wdog, param, 10, 1000); + wdtest_delay(10); + wdtest_recursive(&test_wdog, param, 100, 100); + wdtest_delay(10); + wdtest_recursive(&test_wdog, param, 1000, 10); + wdtest_delay(10); + + /* Random delay ~1us */ wdtest_rand(&test_wdog, param, 1024); + wdtest_delay(10); - /* Random delay ~12345us */ + /* Random delay ~12us */ wdtest_rand(&test_wdog, param, 12345); }
