Skip to content

Commit 2137bc7

Browse files
committed
stmhal: in EXTI interrupt handler wrap uPy calls in gc_lock and nlr_buf.
1 parent 72cfc6e commit 2137bc7

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

stmhal/exti.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
#include <stm32f4xx_hal.h>
66

7+
#include "nlr.h"
78
#include "misc.h"
89
#include "mpconfig.h"
910
#include "qstr.h"
11+
#include "gc.h"
1012
#include "obj.h"
1113
#include "runtime.h"
12-
#include "nlr.h"
1314

1415
#include "pin.h"
1516
#include "exti.h"
@@ -297,14 +298,27 @@ void exti_init(void) {
297298
}
298299
}
299300

301+
// Interrupt handler
300302
void Handle_EXTI_Irq(uint32_t line) {
301303
if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) {
302304
__HAL_GPIO_EXTI_CLEAR_FLAG(1 << line);
303305
if (line < EXTI_NUM_VECTORS) {
304306
exti_vector_t *v = &exti_vector[line];
305307
if (v->callback_obj != mp_const_none) {
306-
// TODO need to wrap this in an nlr_buf; really need a general function for this
307-
mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line));
308+
// When executing code within a handler we must lock the GC to prevent
309+
// any memory allocations. We must also catch any exceptions.
310+
gc_lock();
311+
nlr_buf_t nlr;
312+
if (nlr_push(&nlr) == 0) {
313+
mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line));
314+
nlr_pop();
315+
} else {
316+
// Uncaught exception; disable the callback so it doesn't run again.
317+
v->callback_obj = mp_const_none;
318+
printf("Uncaught exception in EXTI interrupt handler on line %lu\n", line);
319+
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
320+
}
321+
gc_unlock();
308322
}
309323
}
310324
}

0 commit comments

Comments
 (0)