summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/exti.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-04-08 15:21:26 +0100
committerDamien George <damien.p.george@gmail.com>2014-04-08 15:21:26 +0100
commit2137bc7124814b541c4c6eaa02313d5e9bcc47b7 (patch)
tree1f326840f6e54f926dcdb94042ea1e12a5a92919 /stmhal/exti.c
parent72cfc6ef0a3958a9f9e4e3abce45cc9288c251d2 (diff)
downloadmicropython-2137bc7124814b541c4c6eaa02313d5e9bcc47b7.tar.gz
micropython-2137bc7124814b541c4c6eaa02313d5e9bcc47b7.zip
stmhal: in EXTI interrupt handler wrap uPy calls in gc_lock and nlr_buf.
Diffstat (limited to 'stmhal/exti.c')
-rw-r--r--stmhal/exti.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/stmhal/exti.c b/stmhal/exti.c
index afb8c8e139..552efdf080 100644
--- a/stmhal/exti.c
+++ b/stmhal/exti.c
@@ -4,12 +4,13 @@
#include <stm32f4xx_hal.h>
+#include "nlr.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
+#include "gc.h"
#include "obj.h"
#include "runtime.h"
-#include "nlr.h"
#include "pin.h"
#include "exti.h"
@@ -297,14 +298,27 @@ void exti_init(void) {
}
}
+// Interrupt handler
void Handle_EXTI_Irq(uint32_t line) {
if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) {
__HAL_GPIO_EXTI_CLEAR_FLAG(1 << line);
if (line < EXTI_NUM_VECTORS) {
exti_vector_t *v = &exti_vector[line];
if (v->callback_obj != mp_const_none) {
- // TODO need to wrap this in an nlr_buf; really need a general function for this
- mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line));
+ // When executing code within a handler we must lock the GC to prevent
+ // any memory allocations. We must also catch any exceptions.
+ gc_lock();
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line));
+ nlr_pop();
+ } else {
+ // Uncaught exception; disable the callback so it doesn't run again.
+ v->callback_obj = mp_const_none;
+ printf("Uncaught exception in EXTI interrupt handler on line %lu\n", line);
+ mp_obj_print_exception((mp_obj_t)nlr.ret_val);
+ }
+ gc_unlock();
}
}
}