esp32/machine_timer: Deinit all active timers on soft reset.

Otherwise they will keep triggering the callback and access invalid data on
the heap.
This commit is contained in:
Damien George 2019-01-28 16:16:03 +11:00
parent 3d49b157b8
commit 9ac9aa989c
4 changed files with 29 additions and 0 deletions

View File

@ -56,10 +56,14 @@ typedef struct _machine_timer_obj_t {
mp_obj_t callback; mp_obj_t callback;
intr_handle_t handle; intr_handle_t handle;
struct _machine_timer_obj_t *next;
} machine_timer_obj_t; } machine_timer_obj_t;
const mp_obj_type_t machine_timer_type; const mp_obj_type_t machine_timer_type;
STATIC void machine_timer_disable(machine_timer_obj_t *self);
STATIC esp_err_t check_esp_err(esp_err_t code) { STATIC esp_err_t check_esp_err(esp_err_t code) {
if (code) { if (code) {
mp_raise_OSError(code); mp_raise_OSError(code);
@ -68,6 +72,12 @@ STATIC esp_err_t check_esp_err(esp_err_t code) {
return code; return code;
} }
void machine_timer_deinit_all(void) {
while (MP_STATE_PORT(machine_timer_obj_head) != NULL) {
machine_timer_disable(MP_STATE_PORT(machine_timer_obj_head));
}
}
STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_timer_obj_t *self = self_in; machine_timer_obj_t *self = self_in;
@ -88,6 +98,7 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
self->group = (mp_obj_get_int(args[0]) >> 1) & 1; self->group = (mp_obj_get_int(args[0]) >> 1) & 1;
self->index = mp_obj_get_int(args[0]) & 1; self->index = mp_obj_get_int(args[0]) & 1;
self->next = NULL;
return self; return self;
} }
@ -98,6 +109,14 @@ STATIC void machine_timer_disable(machine_timer_obj_t *self) {
esp_intr_free(self->handle); esp_intr_free(self->handle);
self->handle = NULL; self->handle = NULL;
} }
// Remove the timer from the linked-list of active timers
for (machine_timer_obj_t **t = &MP_STATE_PORT(machine_timer_obj_head); *t; t = &(*t)->next) {
if (*t == self) {
*t = (*t)->next;
break;
}
}
} }
STATIC void machine_timer_isr(void *self_in) { STATIC void machine_timer_isr(void *self_in) {
@ -131,6 +150,10 @@ STATIC void machine_timer_enable(machine_timer_obj_t *self) {
check_esp_err(timer_enable_intr(self->group, self->index)); check_esp_err(timer_enable_intr(self->group, self->index));
check_esp_err(timer_isr_register(self->group, self->index, machine_timer_isr, (void*)self, TIMER_FLAGS, &self->handle)); check_esp_err(timer_isr_register(self->group, self->index, machine_timer_isr, (void*)self, TIMER_FLAGS, &self->handle));
check_esp_err(timer_start(self->group, self->index)); check_esp_err(timer_start(self->group, self->index));
// Add the timer to the linked-list of active timers
self->next = MP_STATE_PORT(machine_timer_obj_head);
MP_STATE_PORT(machine_timer_obj_head) = self;
} }
STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {

View File

@ -109,6 +109,8 @@ soft_reset:
} }
} }
machine_timer_deinit_all();
#if MICROPY_PY_THREAD #if MICROPY_PY_THREAD
mp_thread_deinit(); mp_thread_deinit();
#endif #endif

View File

@ -22,5 +22,6 @@ extern const mp_obj_type_t machine_rtc_type;
void machine_pins_init(void); void machine_pins_init(void);
void machine_pins_deinit(void); void machine_pins_deinit(void);
void machine_timer_deinit_all(void);
#endif // MICROPY_INCLUDED_ESP32_MODMACHINE_H #endif // MICROPY_INCLUDED_ESP32_MODMACHINE_H

View File

@ -210,9 +210,12 @@ extern const struct _mp_obj_module_t mp_module_onewire;
#define MP_STATE_PORT MP_STATE_VM #define MP_STATE_PORT MP_STATE_VM
struct _machine_timer_obj_t;
#define MICROPY_PORT_ROOT_POINTERS \ #define MICROPY_PORT_ROOT_POINTERS \
const char *readline_hist[8]; \ const char *readline_hist[8]; \
mp_obj_t machine_pin_irq_handler[40]; \ mp_obj_t machine_pin_irq_handler[40]; \
struct _machine_timer_obj_t *machine_timer_obj_head; \
// type definitions for the specific machine // type definitions for the specific machine