2424#include " us_ticker_api.h"
2525#include " utest/utest.h"
2626#include " watchdog_timing_tests.h"
27+ #include " mbed.h"
28+
29+ #define TIMEOUT_LOWER_LIMIT_MS 1000ULL
30+
31+ // A window to allow to process watchdog kick before timeout occurs.
32+ #define TIME_WINDOW_MS 2UL
2733
2834#define MSG_VALUE_DUMMY " 0"
2935#define CASE_DATA_INVALID 0xffffffffUL
36+ #define CASE_DATA_PHASE2_OK 0xfffffffeUL
3037
3138#define MSG_VALUE_LEN 24
3239#define MSG_KEY_LEN 24
3340
3441#define MSG_KEY_DEVICE_READY " ready"
3542#define MSG_KEY_START_CASE " start_case"
3643#define MSG_KEY_HEARTBEAT " hb"
44+ #define MSG_KEY_DEVICE_RESET " dev_reset"
3745
3846using utest::v1::Case;
3947using utest::v1::Specification;
@@ -47,6 +55,18 @@ struct testcase_data {
4755
4856testcase_data current_case;
4957
58+ bool send_reset_notification (testcase_data *tcdata, uint32_t delay_ms)
59+ {
60+ char msg_value[12 ];
61+ int str_len = snprintf (msg_value, sizeof msg_value, " %02x,%08lx" , tcdata->start_index + tcdata->index , delay_ms);
62+ if (str_len != (sizeof msg_value) - 1 ) {
63+ utest_printf (" Failed to compose a value string to be sent to host." );
64+ return false ;
65+ }
66+ greentea_send_kv (MSG_KEY_DEVICE_RESET, msg_value);
67+ return true ;
68+ }
69+
5070template <uint32_t timeout_ms>
5171void test_timing ()
5272{
@@ -110,6 +130,48 @@ void test_timing()
110130 }
111131}
112132
133+ void test_timeout_lower_limit ()
134+ {
135+ watchdog_features_t features = hal_watchdog_get_platform_features ();
136+ if (TIMEOUT_LOWER_LIMIT_MS > features.max_timeout ) {
137+ TEST_IGNORE_MESSAGE (" Requested timeout value not supported for this target -- ignoring test case." );
138+ return ;
139+ }
140+
141+ // Phase 2. -- verify the test results.
142+ if (current_case.received_data != CASE_DATA_INVALID) {
143+ TEST_ASSERT_EQUAL (CASE_DATA_PHASE2_OK, current_case.received_data );
144+ current_case.received_data = CASE_DATA_INVALID;
145+ return ;
146+ }
147+
148+ // Phase 1. -- run the test code.
149+ watchdog_config_t config = { TIMEOUT_LOWER_LIMIT_MS };
150+ uint32_t sleep_time_ms = (TIMEOUT_LOWER_LIMIT_MS * features.clock_typical_frequency / features.clock_max_frequency ) - TIME_WINDOW_MS;
151+ TEST_ASSERT_EQUAL (WATCHDOG_STATUS_OK, hal_watchdog_init (&config));
152+
153+ // Kick watchdog before timeout.
154+ // Watchdog should not trigger before timeout * clock accuracy.
155+ // If device restarts while waiting for the kick, test fails.
156+
157+ wait_us (sleep_time_ms * 1000 );
158+ hal_watchdog_kick ();
159+
160+ if (send_reset_notification (¤t_case, 2 * TIMEOUT_LOWER_LIMIT_MS) == false ) {
161+ TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
162+ return ;
163+ }
164+ hal_watchdog_kick ();
165+
166+ // Watchdog should fire before twice the timeout value.
167+ wait_us (2 * TIMEOUT_LOWER_LIMIT_MS * 1000 );
168+
169+ // Watchdog reset should have occurred during that wait() above;
170+
171+ hal_watchdog_kick (); // Just to buy some time for testsuite failure handling.
172+ TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
173+ }
174+
113175utest::v1::status_t case_setup (const Case *const source, const size_t index_of_case)
114176{
115177 current_case.index = index_of_case;
@@ -151,6 +213,7 @@ Case cases[] = {
151213 Case (" Timing, 500 ms" , case_setup, test_timing<500UL >),
152214 Case (" Timing, 1000 ms" , case_setup, test_timing<1000UL >),
153215 Case (" Timing, 3000 ms" , case_setup, test_timing<3000UL >),
216+ Case (" timeout accuracy" , case_setup, test_timeout_lower_limit)
154217};
155218
156219Specification specification ((utest::v1::test_setup_handler_t ) testsuite_setup, cases);
0 commit comments