Skip to content

Commit 06229b5

Browse files
committed
shared/runtime/softtimer: Add support for hard callbacks.
Add a flag SOFT_TIMER_HARD_CALLBACK to request that a soft timer's python callback is run directly from the IRQ handler with the scheduler and heap locked, instead of being scheduled via mp_sched_schedule(). Signed-off-by: Chris Webb <chris@arachsys.com>
1 parent f700460 commit 06229b5

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

shared/runtime/softtimer.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,27 @@ void soft_timer_handler(void) {
8888
soft_timer_entry_t *entry = heap;
8989
heap = (soft_timer_entry_t *)mp_pairheap_pop(soft_timer_lt, &heap->pairheap);
9090
if (entry->flags & SOFT_TIMER_FLAG_PY_CALLBACK) {
91-
mp_sched_schedule(entry->py_callback, MP_OBJ_FROM_PTR(entry));
91+
if (entry->flags & SOFT_TIMER_FLAG_HARD_CALLBACK) {
92+
// When executing code within a handler we must lock the scheduler to
93+
// prevent any scheduled callbacks from running, and lock the GC to
94+
// prevent any memory allocations.
95+
mp_sched_lock();
96+
gc_lock();
97+
nlr_buf_t nlr;
98+
if (nlr_push(&nlr) == 0) {
99+
mp_call_function_1(entry->py_callback, MP_OBJ_FROM_PTR(entry));
100+
nlr_pop();
101+
} else {
102+
// Uncaught exception; disable the callback so it doesn't run again.
103+
entry->mode = SOFT_TIMER_MODE_ONE_SHOT;
104+
mp_printf(MICROPY_ERROR_PRINTER, "uncaught exception in timer callback\n");
105+
mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(nlr.ret_val));
106+
}
107+
gc_unlock();
108+
mp_sched_unlock();
109+
} else {
110+
mp_sched_schedule(entry->py_callback, MP_OBJ_FROM_PTR(entry));
111+
}
92112
} else if (entry->c_callback) {
93113
entry->c_callback(entry);
94114
}

shared/runtime/softtimer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#define SOFT_TIMER_FLAG_PY_CALLBACK (1)
3232
#define SOFT_TIMER_FLAG_GC_ALLOCATED (2)
33+
#define SOFT_TIMER_FLAG_HARD_CALLBACK (4)
3334

3435
#define SOFT_TIMER_MODE_ONE_SHOT (1)
3536
#define SOFT_TIMER_MODE_PERIODIC (2)

0 commit comments

Comments
 (0)