7272 */
7373#define SERIAL_FLUSH_TIME_MS 20
7474
75+ #define TIMEOUT_US (1000 * (TIMEOUT_MS))
76+ #define KICK_ADVANCE_US (1000 * (KICK_ADVANCE_MS))
77+ #define SERIAL_FLUSH_TIME_US (1000 * (SERIAL_FLUSH_TIME_MS))
78+
7579using utest::v1::Case;
7680using utest::v1::Specification;
7781using utest::v1::Harness;
@@ -84,13 +88,21 @@ struct testcase_data {
8488 uint32_t received_data;
8589};
8690
87- void release_sem (Semaphore *sem)
91+ testcase_data current_case;
92+
93+ Thread wdg_kicking_thread (osPriorityNormal, 768 );
94+ Semaphore kick_wdg_during_test_teardown (0 , 1 );
95+
96+ void wdg_kicking_thread_fun ()
8897{
89- sem->release ();
98+ kick_wdg_during_test_teardown.acquire ();
99+ Watchdog &watchdog = Watchdog::get_instance ();
100+ while (true ) {
101+ watchdog.kick ();
102+ wait_us (20000 );
103+ }
90104}
91105
92- testcase_data current_case;
93-
94106bool send_reset_notification (testcase_data *tcdata, uint32_t delay_ms)
95107{
96108 char msg_value[12 ];
@@ -124,11 +136,11 @@ void test_simple_reset()
124136 TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
125137 TEST_ASSERT_TRUE (watchdog.is_running ());
126138 // Watchdog should fire before twice the timeout value.
127- wait_ms (2 * TIMEOUT_MS ); // Device reset expected.
139+ wait_us (2 * TIMEOUT_US ); // Device reset expected.
128140
129- // Watchdog reset should have occurred during wait_ms() above;
141+ // Watchdog reset should have occurred during a wait above.
130142
131- watchdog. kick (); // Just to buy some time for testsuite failure handling.
143+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
132144 TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
133145}
134146
@@ -143,8 +155,6 @@ void test_sleep_reset()
143155 }
144156
145157 // Phase 1. -- run the test code.
146- Semaphore sem (0 , 1 );
147- Timeout timeout;
148158 if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
149159 TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
150160 return ;
@@ -154,22 +164,21 @@ void test_sleep_reset()
154164 TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
155165 TEST_ASSERT_TRUE (watchdog.is_running ());
156166 sleep_manager_lock_deep_sleep ();
157- // Watchdog should fire before twice the timeout value.
158- timeout.attach_us (mbed::callback (release_sem, &sem), 1000ULL * (2 * TIMEOUT_MS));
159167 if (sleep_manager_can_deep_sleep ()) {
160168 TEST_ASSERT_MESSAGE (0 , " Deepsleep should be disallowed." );
161169 return ;
162170 }
163- sem.wait (); // Device reset expected.
171+ // Watchdog should fire before twice the timeout value.
172+ ThisThread::sleep_for (2 * TIMEOUT_MS); // Device reset expected.
164173 sleep_manager_unlock_deep_sleep ();
165174
166- // Watchdog reset should have occurred during sem.wait() ( sleep) above;
175+ // Watchdog reset should have occurred during the sleep above.
167176
168- watchdog. kick (); // Just to buy some time for testsuite failure handling.
177+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
169178 TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
170179}
171180
172- #if DEVICE_LOWPOWERTIMER
181+ #if DEVICE_LPTICKER
173182void test_deepsleep_reset ()
174183{
175184 // Phase 2. -- verify the test results.
@@ -180,27 +189,28 @@ void test_deepsleep_reset()
180189 }
181190
182191 // Phase 1. -- run the test code.
183- Semaphore sem (0 , 1 );
184- LowPowerTimeout lp_timeout;
185- if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
192+ if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS + SERIAL_FLUSH_TIME_MS) == false ) {
186193 TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
187194 return ;
188195 }
196+ wait_us (SERIAL_FLUSH_TIME_US); // Wait for the serial buffers to flush.
189197 Watchdog &watchdog = Watchdog::get_instance ();
190198 TEST_ASSERT_FALSE (watchdog.is_running ());
191199 TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
192200 TEST_ASSERT_TRUE (watchdog.is_running ());
193- // Watchdog should fire before twice the timeout value.
194- lp_timeout.attach_us (mbed::callback (release_sem, &sem), 1000ULL * (2 * TIMEOUT_MS));
195- wait_ms (SERIAL_FLUSH_TIME_MS); // Wait for the serial buffers to flush.
196201 if (!sleep_manager_can_deep_sleep ()) {
197202 TEST_ASSERT_MESSAGE (0 , " Deepsleep should be allowed." );
198203 }
199- sem.wait (); // Device reset expected.
200204
201- // Watchdog reset should have occurred during sem.wait() (deepsleep) above;
205+ // The Watchdog reset is allowed to be delayed up to twice the timeout
206+ // value when the deepsleep mode is active.
207+ // To make the test less sensitive to clock/wait accuracy, add 20% extra
208+ // (making tha whole deepsleep wait equal to 2.2 * timeout).
209+ ThisThread::sleep_for (220 * TIMEOUT_MS / 100 ); // Device reset expected.
210+
211+ // Watchdog reset should have occurred during the deepsleep above.
202212
203- watchdog. kick (); // Just to buy some time for testsuite failure handling.
213+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
204214 TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
205215}
206216#endif
@@ -226,13 +236,13 @@ void test_restart_reset()
226236 TEST_ASSERT_FALSE (watchdog.is_running ());
227237 TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
228238 TEST_ASSERT_TRUE (watchdog.is_running ());
229- wait_ms (TIMEOUT_MS / 2UL );
239+ wait_us (TIMEOUT_US / 2 );
230240 TEST_ASSERT_TRUE (watchdog.stop ());
231241 TEST_ASSERT_FALSE (watchdog.is_running ());
232242 // Check that stopping the Watchdog prevents a device reset.
233243 // The watchdog should trigger at, or after the timeout value.
234244 // The watchdog should trigger before twice the timeout value.
235- wait_ms (TIMEOUT_MS / 2UL + TIMEOUT_MS );
245+ wait_us (TIMEOUT_US / 2 + TIMEOUT_US );
236246
237247 if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
238248 TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
@@ -241,11 +251,11 @@ void test_restart_reset()
241251 TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
242252 TEST_ASSERT_TRUE (watchdog.is_running ());
243253 // Watchdog should fire before twice the timeout value.
244- wait_ms (2 * TIMEOUT_MS ); // Device reset expected.
254+ wait_us (2 * TIMEOUT_US ); // Device reset expected.
245255
246- // Watchdog reset should have occurred during that wait() above;
256+ // Watchdog reset should have occurred during a wait above.
247257
248- watchdog. kick (); // Just to buy some time for testsuite failure handling.
258+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
249259 TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
250260}
251261
@@ -266,19 +276,19 @@ void test_kick_reset()
266276 for (int i = 3 ; i; i--) {
267277 // The reset is prevented as long as the watchdog is kicked
268278 // anytime before the timeout.
269- wait_ms (TIMEOUT_MS - KICK_ADVANCE_MS );
279+ wait_us (TIMEOUT_US - KICK_ADVANCE_US );
270280 watchdog.kick ();
271281 }
272282 if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
273283 TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
274284 return ;
275285 }
276286 // Watchdog should fire before twice the timeout value.
277- wait_ms (2 * TIMEOUT_MS ); // Device reset expected.
287+ wait_us (2 * TIMEOUT_US ); // Device reset expected.
278288
279- // Watchdog reset should have occurred during that wait() above;
289+ // Watchdog reset should have occurred during a wait above.
280290
281- watchdog. kick (); // Just to buy some time for testsuite failure handling.
291+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
282292 TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
283293}
284294
@@ -313,6 +323,10 @@ int testsuite_setup(const size_t number_of_cases)
313323 return utest::v1::STATUS_ABORT;
314324 }
315325
326+ // The thread is started here, but feeding the watchdog will start
327+ // when the semaphore is released during a test case teardown.
328+ wdg_kicking_thread.start (mbed::callback (wdg_kicking_thread_fun));
329+
316330 utest_printf (" This test suite is composed of %i test cases. Starting at index %i.\n " , number_of_cases,
317331 current_case.start_index );
318332 return current_case.start_index ;
@@ -322,7 +336,7 @@ Case cases[] = {
322336 Case (" Watchdog reset" , case_setup, test_simple_reset),
323337#if DEVICE_SLEEP
324338 Case (" Watchdog reset in sleep mode" , case_setup, test_sleep_reset),
325- #if DEVICE_LOWPOWERTIMER
339+ #if DEVICE_LPTICKER
326340 Case (" Watchdog reset in deepsleep mode" , case_setup, test_deepsleep_reset),
327341#endif
328342#endif
0 commit comments