mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
shared/runtime/mpirq: Factor out mp_irq_dispatch() and use it.
Separate out a routine to call an arbitrary function with arbitrary argument either directly as a hard-IRQ handler or scheduled as a soft-IRQ handler, adjusting mp_irq_handler() to wrap this. This can then be used to implement other hard/soft callbacks, such as for machine.Timer. Signed-off-by: Chris Webb <chris@arachsys.com>
This commit is contained in:
committed by
Damien George
parent
6c9940b1f6
commit
706cc8d833
@@ -65,9 +65,10 @@ void mp_irq_init(mp_irq_obj_t *self, const mp_irq_methods_t *methods, mp_obj_t p
|
|||||||
self->ishard = false;
|
self->ishard = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_irq_handler(mp_irq_obj_t *self) {
|
int mp_irq_dispatch(mp_obj_t handler, mp_obj_t parent, bool ishard) {
|
||||||
if (self->handler != mp_const_none) {
|
int result = 0;
|
||||||
if (self->ishard) {
|
if (handler != mp_const_none) {
|
||||||
|
if (ishard) {
|
||||||
// When executing code within a handler we must lock the scheduler to
|
// 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 scheduled callbacks from running, and lock the GC to
|
||||||
// prevent any memory allocations.
|
// prevent any memory allocations.
|
||||||
@@ -75,22 +76,30 @@ void mp_irq_handler(mp_irq_obj_t *self) {
|
|||||||
gc_lock();
|
gc_lock();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
mp_call_function_1(self->handler, self->parent);
|
mp_call_function_1(handler, parent);
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
} else {
|
} else {
|
||||||
// Uncaught exception; disable the callback so that it doesn't run again
|
|
||||||
self->methods->trigger(self->parent, 0);
|
|
||||||
self->handler = mp_const_none;
|
|
||||||
mp_printf(MICROPY_ERROR_PRINTER, "Uncaught exception in IRQ callback handler\n");
|
mp_printf(MICROPY_ERROR_PRINTER, "Uncaught exception in IRQ callback handler\n");
|
||||||
mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(nlr.ret_val));
|
mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(nlr.ret_val));
|
||||||
|
result = -1;
|
||||||
}
|
}
|
||||||
gc_unlock();
|
gc_unlock();
|
||||||
mp_sched_unlock();
|
mp_sched_unlock();
|
||||||
} else {
|
} else {
|
||||||
// Schedule call to user function
|
// Schedule call to user function
|
||||||
mp_sched_schedule(self->handler, self->parent);
|
mp_sched_schedule(handler, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mp_irq_handler(mp_irq_obj_t *self) {
|
||||||
|
if (mp_irq_dispatch(self->handler, self->parent, self->ishard) < 0) {
|
||||||
|
// Uncaught exception; disable the callback so that it doesn't run again
|
||||||
|
self->methods->trigger(self->parent, 0);
|
||||||
|
self->handler = mp_const_none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ extern const mp_obj_type_t mp_irq_type;
|
|||||||
|
|
||||||
mp_irq_obj_t *mp_irq_new(const mp_irq_methods_t *methods, mp_obj_t parent);
|
mp_irq_obj_t *mp_irq_new(const mp_irq_methods_t *methods, mp_obj_t parent);
|
||||||
void mp_irq_init(mp_irq_obj_t *self, const mp_irq_methods_t *methods, mp_obj_t parent);
|
void mp_irq_init(mp_irq_obj_t *self, const mp_irq_methods_t *methods, mp_obj_t parent);
|
||||||
|
int mp_irq_dispatch(mp_obj_t handler, mp_obj_t parent, bool ishard);
|
||||||
void mp_irq_handler(mp_irq_obj_t *self);
|
void mp_irq_handler(mp_irq_obj_t *self);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_LIB_UTILS_MPIRQ_H
|
#endif // MICROPY_INCLUDED_LIB_UTILS_MPIRQ_H
|
||||||
|
|||||||
Reference in New Issue
Block a user