summaryrefslogtreecommitdiff
path: root/shared/runtime
diff options
context:
space:
mode:
authorChris Webb <chris@arachsys.com>2025-09-09 15:40:51 +0100
committerDamien George <damien.p.george@gmail.com>2025-09-25 23:59:24 +1000
commit81985d20c98e1550c355263f1d6c7bd6150ee0b4 (patch)
tree94a7e824b29d4fdbc41fb75cfed91d1bbb2ed693 /shared/runtime
parentb9523fd58c02dba74239015bf6b2a1983342a06b (diff)
shared/runtime/mpirq: Check separate hard IRQ stack correctly.
On the zephyr port, hard IRQ handlers run with a separate stack on a different thread, so each call to mp_irq_dispatch() and mp_irq_handler() has to be wrapped with adjustments to the stack-limit checker. Move these adjustments into the shared mp_irq_dispatch(), introducing MICROPY_STACK_SIZE_HARD_IRQ which a port can define to non-zero if it uses a separate stack for hard IRQ handlers. We only need wrap the hard dispatch case. This should reduce binary size on zephyr without affecting other ports. Signed-off-by: Chris Webb <chris@arachsys.com>
Diffstat (limited to 'shared/runtime')
-rw-r--r--shared/runtime/mpirq.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/shared/runtime/mpirq.c b/shared/runtime/mpirq.c
index 0b3489c51..4d848ae7e 100644
--- a/shared/runtime/mpirq.c
+++ b/shared/runtime/mpirq.c
@@ -69,6 +69,15 @@ int mp_irq_dispatch(mp_obj_t handler, mp_obj_t parent, bool ishard) {
int result = 0;
if (handler != mp_const_none) {
if (ishard) {
+ #if MICROPY_STACK_CHECK && MICROPY_STACK_SIZE_HARD_IRQ > 0
+ // This callback executes in an ISR context so the stack-limit
+ // check must be changed to use the ISR stack for the duration
+ // of this function.
+ char *orig_stack_top = MP_STATE_THREAD(stack_top);
+ size_t orig_stack_limit = MP_STATE_THREAD(stack_limit);
+ mp_cstack_init_with_sp_here(MICROPY_STACK_SIZE_HARD_IRQ);
+ #endif
+
// When executing code within a handler we must lock the scheduler to
// prevent any scheduled callbacks from running, and lock the GC to
// prevent any memory allocations.
@@ -85,6 +94,12 @@ int mp_irq_dispatch(mp_obj_t handler, mp_obj_t parent, bool ishard) {
}
gc_unlock();
mp_sched_unlock();
+
+ #if MICROPY_STACK_CHECK && MICROPY_STACK_SIZE_HARD_IRQ > 0
+ // Restore original stack-limit checking values.
+ MP_STATE_THREAD(stack_top) = orig_stack_top;
+ MP_STATE_THREAD(stack_limit) = orig_stack_limit;
+ #endif
} else {
// Schedule call to user function
mp_sched_schedule(handler, parent);