72
72
*/
73
73
#define SERIAL_FLUSH_TIME_MS 20
74
74
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
+
75
79
using utest::v1::Case;
76
80
using utest::v1::Specification;
77
81
using utest::v1::Harness;
@@ -84,13 +88,21 @@ struct testcase_data {
84
88
uint32_t received_data;
85
89
};
86
90
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 ()
88
97
{
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
+ }
90
104
}
91
105
92
- testcase_data current_case;
93
-
94
106
bool send_reset_notification (testcase_data *tcdata, uint32_t delay_ms)
95
107
{
96
108
char msg_value[12 ];
@@ -124,11 +136,11 @@ void test_simple_reset()
124
136
TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
125
137
TEST_ASSERT_TRUE (watchdog.is_running ());
126
138
// 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.
128
140
129
- // Watchdog reset should have occurred during wait_ms() above;
141
+ // Watchdog reset should have occurred during a wait above.
130
142
131
- watchdog. kick (); // Just to buy some time for testsuite failure handling.
143
+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
132
144
TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
133
145
}
134
146
@@ -143,8 +155,6 @@ void test_sleep_reset()
143
155
}
144
156
145
157
// Phase 1. -- run the test code.
146
- Semaphore sem (0 , 1 );
147
- Timeout timeout;
148
158
if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
149
159
TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
150
160
return ;
@@ -154,22 +164,21 @@ void test_sleep_reset()
154
164
TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
155
165
TEST_ASSERT_TRUE (watchdog.is_running ());
156
166
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));
159
167
if (sleep_manager_can_deep_sleep ()) {
160
168
TEST_ASSERT_MESSAGE (0 , " Deepsleep should be disallowed." );
161
169
return ;
162
170
}
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.
164
173
sleep_manager_unlock_deep_sleep ();
165
174
166
- // Watchdog reset should have occurred during sem.wait() ( sleep) above;
175
+ // Watchdog reset should have occurred during the sleep above.
167
176
168
- watchdog. kick (); // Just to buy some time for testsuite failure handling.
177
+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
169
178
TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
170
179
}
171
180
172
- #if DEVICE_LOWPOWERTIMER
181
+ #if DEVICE_LPTICKER
173
182
void test_deepsleep_reset ()
174
183
{
175
184
// Phase 2. -- verify the test results.
@@ -180,27 +189,28 @@ void test_deepsleep_reset()
180
189
}
181
190
182
191
// 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 ) {
186
193
TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
187
194
return ;
188
195
}
196
+ wait_us (SERIAL_FLUSH_TIME_US); // Wait for the serial buffers to flush.
189
197
Watchdog &watchdog = Watchdog::get_instance ();
190
198
TEST_ASSERT_FALSE (watchdog.is_running ());
191
199
TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
192
200
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.
196
201
if (!sleep_manager_can_deep_sleep ()) {
197
202
TEST_ASSERT_MESSAGE (0 , " Deepsleep should be allowed." );
198
203
}
199
- sem.wait (); // Device reset expected.
200
204
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.
202
212
203
- watchdog. kick (); // Just to buy some time for testsuite failure handling.
213
+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
204
214
TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
205
215
}
206
216
#endif
@@ -226,13 +236,13 @@ void test_restart_reset()
226
236
TEST_ASSERT_FALSE (watchdog.is_running ());
227
237
TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
228
238
TEST_ASSERT_TRUE (watchdog.is_running ());
229
- wait_ms (TIMEOUT_MS / 2UL );
239
+ wait_us (TIMEOUT_US / 2 );
230
240
TEST_ASSERT_TRUE (watchdog.stop ());
231
241
TEST_ASSERT_FALSE (watchdog.is_running ());
232
242
// Check that stopping the Watchdog prevents a device reset.
233
243
// The watchdog should trigger at, or after the timeout value.
234
244
// 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 );
236
246
237
247
if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
238
248
TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
@@ -241,11 +251,11 @@ void test_restart_reset()
241
251
TEST_ASSERT_TRUE (watchdog.start (TIMEOUT_MS));
242
252
TEST_ASSERT_TRUE (watchdog.is_running ());
243
253
// 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.
245
255
246
- // Watchdog reset should have occurred during that wait() above;
256
+ // Watchdog reset should have occurred during a wait above.
247
257
248
- watchdog. kick (); // Just to buy some time for testsuite failure handling.
258
+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
249
259
TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
250
260
}
251
261
@@ -266,19 +276,19 @@ void test_kick_reset()
266
276
for (int i = 3 ; i; i--) {
267
277
// The reset is prevented as long as the watchdog is kicked
268
278
// anytime before the timeout.
269
- wait_ms (TIMEOUT_MS - KICK_ADVANCE_MS );
279
+ wait_us (TIMEOUT_US - KICK_ADVANCE_US );
270
280
watchdog.kick ();
271
281
}
272
282
if (send_reset_notification (¤t_case, 2 * TIMEOUT_MS) == false ) {
273
283
TEST_ASSERT_MESSAGE (0 , " Dev-host communication error." );
274
284
return ;
275
285
}
276
286
// 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.
278
288
279
- // Watchdog reset should have occurred during that wait() above;
289
+ // Watchdog reset should have occurred during a wait above.
280
290
281
- watchdog. kick (); // Just to buy some time for testsuite failure handling.
291
+ kick_wdg_during_test_teardown. release (); // For testsuite failure handling.
282
292
TEST_ASSERT_MESSAGE (0 , " Watchdog did not reset the device as expected." );
283
293
}
284
294
@@ -313,6 +323,10 @@ int testsuite_setup(const size_t number_of_cases)
313
323
return utest::v1::STATUS_ABORT;
314
324
}
315
325
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
+
316
330
utest_printf (" This test suite is composed of %i test cases. Starting at index %i.\n " , number_of_cases,
317
331
current_case.start_index );
318
332
return current_case.start_index ;
@@ -322,7 +336,7 @@ Case cases[] = {
322
336
Case (" Watchdog reset" , case_setup, test_simple_reset),
323
337
#if DEVICE_SLEEP
324
338
Case (" Watchdog reset in sleep mode" , case_setup, test_sleep_reset),
325
- #if DEVICE_LOWPOWERTIMER
339
+ #if DEVICE_LPTICKER
326
340
Case (" Watchdog reset in deepsleep mode" , case_setup, test_deepsleep_reset),
327
341
#endif
328
342
#endif
0 commit comments