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

Commitfccab87

Browse files
committed
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 parent20c866d commitfccab87

File tree

4 files changed

+40
-12
lines changed

4 files changed

+40
-12
lines changed

‎ports/rp2/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ typedef intptr_t mp_off_t;
263263
#defineBINARY_INFO_ID_MP_FROZEN 0x4a99d719
264264
#defineMICROPY_FROZEN_LIST_ITEM(name,file) bi_decl(bi_string(BINARY_INFO_TAG_MICROPYTHON, BINARY_INFO_ID_MP_FROZEN, name))
265265

266+
266267
externuint32_trosc_random_u32(void);
267268
externvoidlwip_lock_acquire(void);
268269
externvoidlwip_lock_release(void);

‎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
@@ -57,23 +57,22 @@
5757
if ((TIMEOUT_MS) < 0) { \
5858
__wfe(); \
5959
} else { \
60-
best_effort_wfe_or_timeout(make_timeout_time_ms(TIMEOUT_MS)); \
60+
mp_wfe_or_timeout(TIMEOUT_MS); \
6161
} \
6262
} while (0)
6363

6464
externintmp_interrupt_char;
6565
externringbuf_tstdin_ringbuf;
6666

67+
// Port-specific function to create a wakeup interrupt after timeout_ms and enter WFE
68+
voidmp_wfe_or_timeout(uint32_ttimeout_ms);
69+
6770
uint32_tmp_thread_begin_atomic_section(void);
6871
voidmp_thread_end_atomic_section(uint32_t);
6972

7073
voidmp_hal_set_interrupt_char(intc);
7174
voidmp_hal_time_ns_set_from_rtc(void);
7275

73-
staticinlinevoidmp_hal_delay_us(mp_uint_tus) {
74-
sleep_us(us);
75-
}
76-
7776
staticinlinevoidmp_hal_delay_us_fast(mp_uint_tus) {
7877
busy_wait_us(us);
7978
}

‎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