Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit83e82c5

Browse files
projectgusdpgeorge
authored andcommitted
rp2: Refactor to not use pico-sdk alarm pool functions for sleeping.
The best_effort_wfe_or_timeout() and sleep_us() pico-sdk functions use thepico-sdk alarm pool internally, and that has a bug.Some usages inside pico-sdk (notably multicore_lockout_start_blocking())will still end up calling best_effort_wfe_or_timeout(), although usuallywith "end_of_time" as the timeout value so it should avoid any alarm poolrace conditions.This work was funded through GitHub Sponsors.Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent74fb42a commit83e82c5

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

‎ports/rp2/mphalport.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,31 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
198198
returndid_write ?ret :0;
199199
}
200200

201+
voidmp_hal_delay_us(mp_uint_tus) {
202+
// Avoid calling sleep_us() and invoking the alarm pool by splitting long
203+
// sleeps into an optional longer sleep and a shorter busy-wait
204+
uint64_tend=time_us_64()+us;
205+
if (us>1000) {
206+
mp_hal_delay_ms(us /1000);
207+
}
208+
while (time_us_64()<end) {
209+
// Tight loop busy-wait for accurate timing
210+
}
211+
}
212+
201213
voidmp_hal_delay_ms(mp_uint_tms) {
202-
absolute_time_tt=make_timeout_time_ms(ms);
214+
mp_uint_tstart=mp_hal_ticks_ms();
215+
mp_uint_telapsed=0;
203216
do {
204-
mp_event_handle_nowait();
205-
}while (!best_effort_wfe_or_timeout(t));
217+
mp_event_wait_ms(ms-elapsed);
218+
elapsed=mp_hal_ticks_ms()-start;
219+
}while (elapsed<ms);
206220
}
207221

208222
voidmp_hal_time_ns_set_from_rtc(void) {
209-
//Delay at least oneRTCclock cycle so it's registers have updated with the most
210-
//recent time settings.
211-
sleep_us(23);
223+
//OutstandingRTCregister writes need at least two RTC clock cycles to
224+
//update. (See RP2040 datasheet section 4.8.4 "Reference clock").
225+
mp_hal_delay_us(44);
212226

213227
// Sample RTC and time_us_64() as close together as possible, so the offset
214228
// calculated for the latter can be as accurate as possible.
@@ -295,3 +309,17 @@ void soft_timer_init(void) {
295309
hardware_alarm_claim(MICROPY_HW_SOFT_TIMER_ALARM_NUM);
296310
hardware_alarm_set_callback(MICROPY_HW_SOFT_TIMER_ALARM_NUM,soft_timer_hardware_callback);
297311
}
312+
313+
voidmp_wfe_or_timeout(uint32_ttimeout_ms) {
314+
soft_timer_entry_ttimer;
315+
316+
// Note the timer doesn't have an associated callback, it just exists to create a
317+
// hardware interrupt to wake the CPU
318+
soft_timer_static_init(&timer,SOFT_TIMER_MODE_ONE_SHOT,0,NULL);
319+
soft_timer_insert(&timer,timeout_ms);
320+
321+
__wfe();
322+
323+
// Clean up the timer node if it's not already
324+
soft_timer_remove(&timer);
325+
}

‎ports/rp2/mphalport.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,22 @@
6262
if ((TIMEOUT_MS) < 0) { \
6363
__wfe(); \
6464
} else { \
65-
best_effort_wfe_or_timeout(make_timeout_time_ms(TIMEOUT_MS)); \
65+
mp_wfe_or_timeout(TIMEOUT_MS); \
6666
} \
6767
} while (0)
6868

6969
externintmp_interrupt_char;
7070
externringbuf_tstdin_ringbuf;
7171

72+
// Port-specific function to create a wakeup interrupt after timeout_ms and enter WFE
73+
voidmp_wfe_or_timeout(uint32_ttimeout_ms);
74+
7275
uint32_tmp_thread_begin_atomic_section(void);
7376
voidmp_thread_end_atomic_section(uint32_t);
7477

7578
voidmp_hal_set_interrupt_char(intc);
7679
voidmp_hal_time_ns_set_from_rtc(void);
7780

78-
staticinlinevoidmp_hal_delay_us(mp_uint_tus) {
79-
sleep_us(us);
80-
}
81-
8281
staticinlinevoidmp_hal_delay_us_fast(mp_uint_tus) {
8382
busy_wait_us(us);
8483
}

‎shared/runtime/softtimer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ void soft_timer_handler(void) {
8989
heap= (soft_timer_entry_t*)mp_pairheap_pop(soft_timer_lt,&heap->pairheap);
9090
if (entry->flags&SOFT_TIMER_FLAG_PY_CALLBACK) {
9191
mp_sched_schedule(entry->py_callback,MP_OBJ_FROM_PTR(entry));
92-
}else {
92+
}elseif (entry->c_callback){
9393
entry->c_callback(entry);
9494
}
9595
if (entry->mode==SOFT_TIMER_MODE_PERIODIC) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp