From 78b3fe56897d029f2786256d83dd2fecacb34637 Mon Sep 17 00:00:00 2001 From: Thomas Wenrich Date: Sat, 22 May 2021 13:38:20 +0200 Subject: [PATCH] esp32/machine_rtc: Preserve RTC user memory over most reset causes. The user memory area - accessible by machine.RTC.memory() -- will now survive most reboot causes. A power-on reset (also caused by the EN pin on some boards) will clean the memory. When this happens, the magic number not found in the user memory will cause initialization. After other resets (triggered by watchdogs, machine.reset(), ...), the user is responsible to check and validate the contents of the user area. This new behaviour can be changed by enabling MICROPY_HW_RTC_MEM_INIT_ALWAYS: in that case the RTC memory is always cleared on boot. Signed-off-by: Thomas Wenrich --- ports/esp32/machine_rtc.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index f7b3ae66f2..cbbfb4b84c 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -60,14 +60,24 @@ typedef struct _machine_rtc_obj_t { #define MICROPY_HW_RTC_USER_MEM_MAX 2048 #endif +// A board can enable MICROPY_HW_RTC_MEM_INIT_ALWAYS to always clear out RTC memory on boot. +// Defaults to RTC_NOINIT_ATTR so the user memory survives WDT resets and the like. +#if MICROPY_HW_RTC_MEM_INIT_ALWAYS +#define _USER_MEM_ATTR RTC_DATA_ATTR +#else +#define _USER_MEM_ATTR RTC_NOINIT_ATTR +#endif + // Optionally compile user memory functionality if the size of memory is greater than 0 #if MICROPY_HW_RTC_USER_MEM_MAX > 0 #define MEM_MAGIC 0x75507921 -RTC_DATA_ATTR uint32_t rtc_user_mem_magic; -RTC_DATA_ATTR uint16_t rtc_user_mem_len; -RTC_DATA_ATTR uint8_t rtc_user_mem_data[MICROPY_HW_RTC_USER_MEM_MAX]; +_USER_MEM_ATTR uint32_t rtc_user_mem_magic; +_USER_MEM_ATTR uint16_t rtc_user_mem_len; +_USER_MEM_ATTR uint8_t rtc_user_mem_data[MICROPY_HW_RTC_USER_MEM_MAX]; #endif +#undef _USER_MEM_ATTR + // singleton RTC object STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}}; @@ -80,6 +90,13 @@ STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, s // check arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); + #if MICROPY_HW_RTC_USER_MEM_MAX > 0 + if (rtc_user_mem_magic != MEM_MAGIC) { + rtc_user_mem_magic = MEM_MAGIC; + rtc_user_mem_len = 0; + } + #endif + // return constant object return (mp_obj_t)&machine_rtc_obj; } @@ -130,13 +147,6 @@ STATIC mp_obj_t machine_rtc_init(mp_obj_t self_in, mp_obj_t date) { mp_obj_t args[2] = {self_in, date}; machine_rtc_datetime_helper(2, args); - #if MICROPY_HW_RTC_USER_MEM_MAX > 0 - if (rtc_user_mem_magic != MEM_MAGIC) { - rtc_user_mem_magic = MEM_MAGIC; - rtc_user_mem_len = 0; - } - #endif - return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_init_obj, machine_rtc_init);