diff options
author | Angus Gratton <angus@redyak.com.au> | 2024-07-03 15:52:31 +1000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-07-23 16:02:59 +1000 |
commit | 9db16cfe31c70a75bfd8a8d93401ff7f6010b1ae (patch) | |
tree | 154b10037cc97296576750217fb6f79254cb0c87 | |
parent | eced9d86a709f3f267edc7bc08e52115d0c0c9df (diff) |
rp2: Fix wakeup from WFE on core1.
If core1 executes `mp_wfe_or_timeout()` then it needs to receive an
interrupt or a SEV to resume execution, but the soft timer interrupt only
fires on core 0. This fix adds a SEV to the soft timer interrupt handler.
This issue was masked by the issue fixed in the previous commit, as WFE
previously wasn't suspending properly.
Verified via the existing thread_sleep2 test.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
-rw-r--r-- | ports/rp2/mphalport.c | 7 | ||||
-rw-r--r-- | ports/rp2/mpthreadport.c | 2 | ||||
-rw-r--r-- | ports/rp2/mpthreadport.h | 4 |
3 files changed, 12 insertions, 1 deletions
diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c index 3fe5357c8..ad51cf8e2 100644 --- a/ports/rp2/mphalport.c +++ b/ports/rp2/mphalport.c @@ -228,6 +228,13 @@ static void soft_timer_hardware_callback(unsigned int alarm_num) { // The timer alarm ISR needs to call here and trigger PendSV dispatch via // a second ISR, as PendSV may be currently suspended by the other CPU. pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler); + + // This ISR only runs on core0, but if core1 is running Python code then it + // may be blocked in WFE so wake it up as well. Unfortunately this also sets + // the event flag on core0, so a subsequent WFE on this core will not suspend + if (core1_entry != NULL) { + __sev(); + } } void soft_timer_init(void) { diff --git a/ports/rp2/mpthreadport.c b/ports/rp2/mpthreadport.c index 5b8e804f9..0d3b343ca 100644 --- a/ports/rp2/mpthreadport.c +++ b/ports/rp2/mpthreadport.c @@ -39,7 +39,7 @@ extern uint8_t __StackTop, __StackBottom; void *core_state[2]; // This will be non-NULL while Python code is executing. -static void *(*core1_entry)(void *) = NULL; +core_entry_func_t core1_entry = NULL; static void *core1_arg = NULL; static uint32_t *core1_stack = NULL; diff --git a/ports/rp2/mpthreadport.h b/ports/rp2/mpthreadport.h index 7982de96a..67a0da0e9 100644 --- a/ports/rp2/mpthreadport.h +++ b/ports/rp2/mpthreadport.h @@ -32,6 +32,10 @@ typedef struct mutex mp_thread_mutex_t; extern void *core_state[2]; +typedef void *(*core_entry_func_t)(void *); + +extern core_entry_func_t core1_entry; + void mp_thread_init(void); void mp_thread_deinit(void); void mp_thread_gc_others(void); |