update watchdog implementation for espressif

This commit is contained in:
MicroDev 2023-03-15 13:18:13 +05:30
parent 5e0dce286e
commit 0acf2e8c9b
No known key found for this signature in database
GPG Key ID: 2C0867BE60967730
1 changed files with 42 additions and 14 deletions

View File

@ -33,9 +33,18 @@
#include "esp_task_wdt.h"
extern void esp_task_wdt_isr_user_handler(void);
void esp_task_wdt_isr_user_handler(void) {
// just delete, deiniting TWDT in isr context causes a crash
if (esp_task_wdt_delete(NULL) == ESP_OK) {
watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj;
self->mode = WATCHDOGMODE_NONE;
}
// schedule watchdog timeout exception
mp_obj_exception_clear_traceback(MP_OBJ_FROM_PTR(&mp_watchdog_timeout_exception));
MP_STATE_THREAD(mp_pending_exception) = &mp_watchdog_timeout_exception;
#if MICROPY_ENABLE_SCHEDULER
if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) {
MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
@ -44,12 +53,13 @@ void esp_task_wdt_isr_user_handler(void) {
}
void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) {
if (esp_task_wdt_reset() != ESP_OK) {
mp_raise_RuntimeError(translate("watchdog not initialized"));
}
esp_task_wdt_reset();
}
void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) {
if (self->mode == WATCHDOGMODE_NONE) {
return;
}
if (esp_task_wdt_delete(NULL) == ESP_OK && esp_task_wdt_deinit() == ESP_OK) {
self->mode = WATCHDOGMODE_NONE;
}
@ -59,11 +69,11 @@ void watchdog_reset(void) {
common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj);
}
static void wdt_config(watchdog_watchdogtimer_obj_t *self) {
static void wdt_config(uint32_t timeout, watchdog_watchdogmode_t mode) {
// enable panic hanler in WATCHDOGMODE_RESET mode
// initialize Task Watchdog Timer (TWDT)
if (esp_task_wdt_init((uint32_t)self->timeout, (self->mode == WATCHDOGMODE_RESET)) != ESP_OK) {
mp_raise_RuntimeError(translate("Initialization failed due to lack of memory"));
if (esp_task_wdt_init(timeout, mode == WATCHDOGMODE_RESET) != ESP_OK) {
mp_raise_msg(&mp_type_MemoryError, NULL);
}
esp_task_wdt_add(NULL);
}
@ -73,12 +83,17 @@ mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) {
}
void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_float_t new_timeout) {
if ((uint64_t)new_timeout > UINT32_MAX) {
mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value"));
if (!(self->timeout < new_timeout || self->timeout > new_timeout)) {
return;
}
if ((uint32_t)self->timeout != (uint32_t)new_timeout) {
self->timeout = new_timeout;
wdt_config(self);
if ((uint64_t)new_timeout > UINT32_MAX) {
mp_raise_ValueError_varg(translate("%q must be <= %d"), MP_QSTR_timeout, UINT32_MAX);
}
self->timeout = new_timeout;
if (self->mode != WATCHDOGMODE_NONE) {
wdt_config(new_timeout, self->mode);
}
}
@ -87,8 +102,21 @@ watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_
}
void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t new_mode) {
if (self->mode != new_mode) {
self->mode = new_mode;
wdt_config(self);
if (self->mode == new_mode) {
return;
}
switch (new_mode) {
case WATCHDOGMODE_NONE:
common_hal_watchdog_deinit(self);
break;
case WATCHDOGMODE_RAISE:
case WATCHDOGMODE_RESET:
wdt_config(self->timeout, new_mode);
break;
default:
return;
}
self->mode = new_mode;
}