diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 6ee4d816a5..d7f95091c8 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-10 16:56+0530\n" +"POT-Creation-Date: 2020-12-17 19:42+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -936,6 +936,10 @@ msgstr "" msgid "Filters too complex" msgstr "" +#: ports/esp32s2/common-hal/dualbank/__init__.c +msgid "Firmware image is invalid" +msgstr "" + #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" msgstr "" @@ -1420,10 +1424,6 @@ msgstr "" msgid "Not settable" msgstr "" -#: ports/esp32s2/common-hal/ota/__init__.c -msgid "OTA Update Failed" -msgstr "" - #: shared-bindings/util.c msgid "" "Object has been deinitialized and can no longer be used. Create a new object." @@ -1911,10 +1911,6 @@ msgstr "" msgid "Unable to read color palette data" msgstr "" -#: ports/esp32s2/common-hal/ota/__init__.c -msgid "Unable to switch boot partition" -msgstr "" - #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -1983,6 +1979,10 @@ msgstr "" msgid "Unsupported pull value." msgstr "" +#: ports/esp32s2/common-hal/dualbank/__init__.c +msgid "Update Failed" +msgstr "" + #: ports/nrf/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Descriptor.c msgid "Value length != required fixed length" @@ -3210,7 +3210,7 @@ msgstr "" msgid "offset is too large" msgstr "" -#: shared-bindings/ota/__init__.c +#: shared-bindings/dualbank/__init__.c msgid "offset must be >= 0" msgstr "" diff --git a/ports/esp32s2/common-hal/ota/__init__.c b/ports/esp32s2/common-hal/dualbank/__init__.c similarity index 76% rename from ports/esp32s2/common-hal/ota/__init__.c rename to ports/esp32s2/common-hal/dualbank/__init__.c index 5ea25fb5d4..0f468a036b 100644 --- a/ports/esp32s2/common-hal/ota/__init__.c +++ b/ports/esp32s2/common-hal/dualbank/__init__.c @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#include "common-hal/ota/__init__.h" -#include "shared-bindings/ota/__init__.h" +#include "common-hal/dualbank/__init__.h" +#include "shared-bindings/dualbank/__init__.h" #include @@ -35,21 +35,24 @@ static const esp_partition_t *update_partition = NULL; static esp_ota_handle_t update_handle = 0; -static bool ota_inited = false; -static const char *TAG = "OTA"; +static const char *TAG = "dualbank"; -void ota_reset(void) { - update_handle = 0; - update_partition = NULL; - ota_inited = false; +void dualbank_reset(void) { + // should use `abort` instead of `end` + // but not in idf v4.2 + // esp_ota_abort(update_handle); + if (esp_ota_end(update_handle) == ESP_OK) { + update_handle = 0; + update_partition = NULL; + } } static void __attribute__((noreturn)) task_fatal_error(void) { ESP_LOGE(TAG, "Exiting task due to fatal error..."); - mp_raise_RuntimeError(translate("OTA Update Failed")); + mp_raise_RuntimeError(translate("Update Failed")); } -void common_hal_ota_flash(const void *buf, const size_t len, const int32_t offset) { +void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t offset) { esp_err_t err; const esp_partition_t *running = esp_ota_get_running_partition(); @@ -67,7 +70,7 @@ void common_hal_ota_flash(const void *buf, const size_t len, const int32_t offse assert(update_partition != NULL); } - if (!ota_inited) { + if (update_handle == 0) { if (len > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) { esp_app_desc_t new_app_info; memcpy(&new_app_info, &((char *)buf)[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t)); @@ -102,14 +105,13 @@ void common_hal_ota_flash(const void *buf, const size_t len, const int32_t offse ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err)); task_fatal_error(); } - ota_inited = true; } else { ESP_LOGE(TAG, "received package is not fit len"); task_fatal_error(); } } - if (offset == -1) { + if (offset == 0) { err = esp_ota_write(update_handle, buf, len); } else { err = esp_ota_write_with_offset(update_handle, buf, len, offset); @@ -120,31 +122,18 @@ void common_hal_ota_flash(const void *buf, const size_t len, const int32_t offse } } -void common_hal_ota_finish(void) { - if (ota_inited) { - esp_err_t err; - - err = esp_ota_end(update_handle); - if (err != ESP_OK) { - if (err == ESP_ERR_OTA_VALIDATE_FAILED) { - ESP_LOGE(TAG, "Image validation failed, image is corrupted"); - } - ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err)); - task_fatal_error(); +void common_hal_dualbank_switch(void) { + if (esp_ota_end(update_handle) == ESP_OK) { + update_handle = 0; + update_partition = NULL; + } + esp_err_t err = esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL)); + if (err != ESP_OK) { + if (err == ESP_ERR_OTA_VALIDATE_FAILED) { + ESP_LOGE(TAG, "Image validation failed, image is corrupted"); + mp_raise_RuntimeError(translate("Firmware image is invalid")); } - - err = esp_ota_set_boot_partition(update_partition); - if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); - task_fatal_error(); - } - - ota_reset(); - } -} - -void common_hal_ota_switch(void) { - if (esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL)) != ESP_OK) { - mp_raise_RuntimeError(translate("Unable to switch boot partition")); + ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); + task_fatal_error(); } } diff --git a/ports/esp32s2/common-hal/ota/__init__.h b/ports/esp32s2/common-hal/dualbank/__init__.h similarity index 84% rename from ports/esp32s2/common-hal/ota/__init__.h rename to ports/esp32s2/common-hal/dualbank/__init__.h index 983b57e3f2..8b18336c94 100644 --- a/ports/esp32s2/common-hal/ota/__init__.h +++ b/ports/esp32s2/common-hal/dualbank/__init__.h @@ -24,9 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_OTA___INIT___H -#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_OTA___INIT___H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DUALBANK___INIT___H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DUALBANK___INIT___H -extern void ota_reset(void); +extern void dualbank_reset(void); -#endif //MICROPY_INCLUDED_ESP32S2_COMMON_HAL_OTA___INIT___H +#endif //MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DUALBANK___INIT___H diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index da231107fb..2ad8afb51c 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -19,11 +19,11 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_CANIO = 1 CIRCUITPY_COUNTIO = 1 +CIRCUITPY_DUALBANK = 1 CIRCUITPY_FREQUENCYIO = 1 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 1 CIRCUITPY_NVM = 1 -CIRCUITPY_OTA = 1 # We don't have enough endpoints to include MIDI. CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WIFI = 1 diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 201d9962e2..a56ac61c81 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -41,7 +41,7 @@ #include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" -#include "common-hal/ota/__init__.h" +#include "common-hal/dualbank/__init__.h" #include "common-hal/ps2io/Ps2.h" #include "common-hal/pulseio/PulseIn.h" #include "common-hal/pwmio/PWMOut.h" @@ -124,8 +124,8 @@ void reset_port(void) { analogout_reset(); #endif -#if CIRCUITPY_OTA - ota_reset(); +#if CIRCUITPY_DUALBANK + dualbank_reset(); #endif #if CIRCUITPY_PS2IO diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 68e806d4b2..a871479141 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -205,8 +205,8 @@ endif ifeq ($(CIRCUITPY_OS),1) SRC_PATTERNS += os/% endif -ifeq ($(CIRCUITPY_OTA),1) -SRC_PATTERNS += ota/% +ifeq ($(CIRCUITPY_DUALBANK),1) +SRC_PATTERNS += dualbank/% endif ifeq ($(CIRCUITPY_PIXELBUF),1) SRC_PATTERNS += _pixelbuf/% @@ -350,7 +350,7 @@ SRC_COMMON_HAL_ALL = \ nvm/ByteArray.c \ nvm/__init__.c \ os/__init__.c \ - ota/__init__.c \ + dualbank/__init__.c \ ps2io/Ps2.c \ ps2io/__init__.c \ pulseio/PulseIn.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 6a0daa7e9b..08c92a77ef 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -539,11 +539,11 @@ extern const struct _mp_obj_module_t os_module; #define OS_MODULE_ALT_NAME #endif -#if CIRCUITPY_OTA -extern const struct _mp_obj_module_t ota_module; -#define OTA_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ota), (mp_obj_t)&ota_module }, +#if CIRCUITPY_DUALBANK +extern const struct _mp_obj_module_t dualbank_module; +#define DUALBANK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_dualbank), (mp_obj_t)&dualbank_module }, #else -#define OTA_MODULE +#define DUALBANK_MODULE #endif #if CIRCUITPY_PEW @@ -834,7 +834,7 @@ extern const struct _mp_obj_module_t wifi_module; NETWORK_MODULE \ SOCKET_MODULE \ WIZNET_MODULE \ - OTA_MODULE \ + DUALBANK_MODULE \ PEW_MODULE \ PIXELBUF_MODULE \ PS2IO_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 09074bf53c..af1dccf024 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -179,8 +179,8 @@ CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM) CIRCUITPY_OS ?= 1 CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) -CIRCUITPY_OTA ?= 0 -CFLAGS += -DCIRCUITPY_OTA=$(CIRCUITPY_OTA) +CIRCUITPY_DUALBANK ?= 0 +CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) diff --git a/shared-bindings/ota/__init__.c b/shared-bindings/dualbank/__init__.c similarity index 55% rename from shared-bindings/ota/__init__.c rename to shared-bindings/dualbank/__init__.c index 8ecc6d9c41..8021ab18b9 100644 --- a/shared-bindings/ota/__init__.c +++ b/shared-bindings/dualbank/__init__.c @@ -24,19 +24,20 @@ * THE SOFTWARE. */ -#include "shared-bindings/ota/__init__.h" +#include "shared-bindings/dualbank/__init__.h" -//| """OTA Module +//| """DUALBANK Module //| -//| The `ota` module implements over-the-air update. +//| The `dualbank` module adds ability to update and switch +//| between the two app partitions. //| -//| There are two identical ota partitions ota_0/1, these -//| contain different firmware versions. +//| There are two identical partitions, these contain different +//| firmware versions. //| Having two partitions enables rollback functionality. //| //| The two partitions are defined as boot partition and -//| next-update partition. Calling `ota.flash()` writes the -//| next-update partition. +//| next-update partition. Calling `dualbank.flash()` writes +//| the next-update partition. //| //| After the next-update partition is written a validation //| check is performed and on a successful validation this @@ -47,81 +48,68 @@ //| //| .. code-block:: python //| -//| import ota +//| import dualbank //| -//| ota.flash(buffer, offset) -//| ota.finish() +//| dualbank.flash(buffer, offset) +//| dualbank.switch() //| """ //| ... //| -//| def switch() -> None: -//| """Switches the boot partition. On next reset, -//| firmware will be loaded from the partition -//| just switched over to.""" -//| ... -//| -STATIC mp_obj_t ota_switch(void) { - common_hal_ota_switch(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(ota_switch_obj, ota_switch); - -//| def finish() -> None: -//| """Validates flashed firmware, sets next boot partition. -//| **Must be called** after the firmware has been -//| completely written into the flash using `ota.flash()`. -//| -//| This is to be called only once per update.""" -//| ... -//| -STATIC mp_obj_t ota_finish(void) { - common_hal_ota_finish(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(ota_finish_obj, ota_finish); - //| def flash(*buffer: ReadableBuffer, offset: int=0) -> None: -//| """Writes one of two OTA partitions at the given offset. -//| -//| The default offset is 0. It is necessary to provide the -//| offset when writing in discontinous chunks. +//| """Writes one of two app partitions at the given offset. //| //| This can be called multiple times when flashing the firmware -//| in small chunks.""" +//| in small chunks. +//| """ //| ... //| -STATIC mp_obj_t ota_flash(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t dualbank_flash(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_offset }; static const mp_arg_t allowed_args[] = { { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_offset, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_offset, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (args[ARG_offset].u_int < -1) { + if (args[ARG_offset].u_int < 0) { mp_raise_ValueError(translate("offset must be >= 0")); } mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - common_hal_ota_flash(bufinfo.buf, bufinfo.len, args[ARG_offset].u_int); + common_hal_dualbank_flash(bufinfo.buf, bufinfo.len, args[ARG_offset].u_int); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ota_flash_obj, 0, ota_flash); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(dualbank_flash_obj, 0, dualbank_flash); -STATIC const mp_rom_map_elem_t ota_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ota) }, - { MP_ROM_QSTR(MP_QSTR_switch), MP_ROM_PTR(&ota_switch_obj) }, - { MP_ROM_QSTR(MP_QSTR_finish), MP_ROM_PTR(&ota_finish_obj) }, - { MP_ROM_QSTR(MP_QSTR_flash), MP_ROM_PTR(&ota_flash_obj) }, +//| def switch() -> None: +//| """Switches the boot partition. +//| +//| On next reset, firmware will be loaded from the partition +//| just switched over to. +//| """ +//| ... +//| +STATIC mp_obj_t dualbank_switch(void) { + common_hal_dualbank_switch(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(dualbank_switch_obj, dualbank_switch); + +STATIC const mp_rom_map_elem_t dualbank_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_dualbank) }, + // module functions + { MP_ROM_QSTR(MP_QSTR_flash), MP_ROM_PTR(&dualbank_flash_obj) }, + { MP_ROM_QSTR(MP_QSTR_switch), MP_ROM_PTR(&dualbank_switch_obj) }, }; -STATIC MP_DEFINE_CONST_DICT(ota_module_globals, ota_module_globals_table); +STATIC MP_DEFINE_CONST_DICT(dualbank_module_globals, dualbank_module_globals_table); -const mp_obj_module_t ota_module = { +const mp_obj_module_t dualbank_module = { .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&ota_module_globals, + .globals = (mp_obj_dict_t*)&dualbank_module_globals, }; diff --git a/shared-bindings/ota/__init__.h b/shared-bindings/dualbank/__init__.h similarity index 78% rename from shared-bindings/ota/__init__.h rename to shared-bindings/dualbank/__init__.h index 82273f975a..7edbc6d68a 100644 --- a/shared-bindings/ota/__init__.h +++ b/shared-bindings/dualbank/__init__.h @@ -24,13 +24,12 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_OTA___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_OTA___INIT___H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DUALBANK___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DUALBANK___INIT___H #include "py/runtime.h" -extern void common_hal_ota_switch(void); -extern void common_hal_ota_finish(void); -extern void common_hal_ota_flash(const void *buf, const size_t len, const int32_t offset); +extern void common_hal_dualbank_switch(void); +extern void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t offset); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_OTA___INIT___H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DUALBANK___INIT___H