@@ -72,6 +72,8 @@ static bool repeating_timer_callback(struct repeating_timer *t) {
7272#endif
7373
7474int issue_195_test (void );
75+ int issue_1812_test (void );
76+ int issue_1953_test (void );
7577
7678int main () {
7779 setup_default_uart ();
@@ -192,13 +194,19 @@ int main() {
192194
193195 PICOTEST_END_SECTION ();
194196
197+
195198 PICOTEST_START_SECTION ("Repeating timertest" );
196199 for (uint i = 0 ;i < NUM_REPEATING_TIMERS ;i ++ ) {
197200
198201 add_repeating_timer_us (500 + (rand () & 1023 ), repeating_timer_callback , (void * )(uintptr_t )i , repeating_timers + i );
199202 }
200203
201- sleep_ms (3000 );
204+ // issue #1953 will lockup here if sleep_us >= 6us (PICO_TIME_SLEEP_OVERHEAD_ADJUST_US)
205+ absolute_time_t timeout = make_timeout_time_ms (3000 );
206+ while (absolute_time_diff_us (get_absolute_time (), timeout ) > 0 ) {
207+ sleep_us (5 );
208+ }
209+
202210 uint callbacks = 0 ;
203211 for (uint i = 0 ;i < NUM_REPEATING_TIMERS ;i ++ ) {
204212 PICOTEST_CHECK (cancel_repeating_timer (repeating_timers + i ), "Cancelling repeating timer should succeed" );
@@ -226,6 +234,17 @@ int main() {
226234 if (issue_195_test ()) {
227235 return -1 ;
228236 }
237+ issue_1812_test ();
238+
239+ // Destroy alarm pools (except for default)
240+ for (uint i = 0 ; i < NUM_ALARMS ; i ++ ) {
241+ if (i != alarm_pool_timer_alarm_num (alarm_pool_get_default ())) {
242+ alarm_pool_destroy (pools [i ]);
243+ pools [i ] = 0 ;
244+ }
245+ }
246+
247+ issue_1953_test ();
229248
230249 PICOTEST_END_TEST ();
231250}
@@ -255,3 +274,54 @@ int issue_195_test(void) {
255274 return 0 ;
256275}
257276
277+ // Setting an alarm should not swallow a sev
278+ int issue_1812_test (void ) {
279+ PICOTEST_START_SECTION ("Issue #1812 defect - Setting an alarm should not ignore a sev" );
280+
281+ __sev (); // Make sure the call below does not ignore this
282+ absolute_time_t before = get_absolute_time ();
283+ bool result = best_effort_wfe_or_timeout (make_timeout_time_ms (1000 ));
284+ int64_t diff = absolute_time_diff_us (before , get_absolute_time ());
285+ PICOTEST_CHECK (diff < 250 && !result , "sev ignored by best_effort_wfe_or_timeout" )
286+
287+ PICOTEST_END_SECTION ();
288+ return 0 ;
289+ }
290+
291+ static bool timer_callback_issue_1953 (repeating_timer_t * rt ) {
292+ static int counter ;
293+ counter ++ ;
294+ return true;
295+ }
296+
297+ // Callback should only occur if the alarm is set in the past
298+ static void alarm_pool_stuck_issue_1953 (uint alarm ) {
299+ hard_assert (false);
300+ }
301+
302+ int issue_1953_test (void ) {
303+ PICOTEST_START_SECTION ("Issue #1953 defect - Alarm can be set in the past" );
304+ int alarm = hardware_alarm_claim_unused (true);
305+ hardware_alarm_set_callback (alarm , alarm_pool_stuck_issue_1953 );
306+
307+ repeating_timer_t timer1 ;
308+ repeating_timer_t timer2 ;
309+
310+ assert (add_repeating_timer_us (10 , timer_callback_issue_1953 , NULL , & timer1 ));
311+ assert (add_repeating_timer_us (100 , timer_callback_issue_1953 , NULL , & timer2 ));
312+
313+ int iterations = 0 ;
314+ while (iterations < 100 ) {
315+ iterations ++ ;
316+ hardware_alarm_set_target (alarm , make_timeout_time_ms (1000 ));
317+ sleep_us (500 ); // lockup in here without the fix for #1953
318+ hardware_alarm_cancel (alarm );
319+ }
320+
321+ cancel_repeating_timer (& timer1 );
322+ cancel_repeating_timer (& timer2 );
323+
324+ hardware_alarm_unclaim (alarm );
325+ PICOTEST_END_SECTION ();
326+ return 0 ;
327+ }
0 commit comments