From a620419b595d3f77fddbfaf1f7f4cc40098e99d2 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Tue, 7 May 2024 08:52:29 +0100 Subject: [PATCH] Add MG_OTA_ESP32 --- mongoose.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ mongoose.h | 19 ++++++---------- src/arch_esp32.h | 3 ++- src/device.h | 7 +++--- src/ota.h | 1 + src/ota_esp32.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 src/ota_esp32.c diff --git a/mongoose.c b/mongoose.c index db150f2d..cacfb217 100644 --- a/mongoose.c +++ b/mongoose.c @@ -6073,6 +6073,62 @@ MG_IRAM void mg_ota_boot(void) { } #endif +#ifdef MG_ENABLE_LINES +#line 1 "src/ota_esp32.c" +#endif + + +#if MG_ARCH == MG_ARCH_ESP32 && MG_OTA == MG_OTA_ESP32 + +static const esp_partition_t *s_ota_update_partition; +static esp_ota_handle_t s_ota_update_handle; +static bool s_ota_success; + +// Those empty macros do nothing, but mark places in the code which could +// potentially trigger a watchdog reboot due to the log flash erase operation +#define disable_wdt() +#define enable_wdt() + +bool mg_ota_begin(size_t new_firmware_size) { + if (s_ota_update_partition != NULL) { + MG_ERROR(("Update in progress. Call mg_ota_end() ?")); + return false; + } else { + s_ota_success = false; + disable_wdt(); + s_ota_update_partition = esp_ota_get_next_update_partition(NULL); + esp_err_t err = esp_ota_begin(s_ota_update_partition, new_firmware_size, + &s_ota_update_handle); + enable_wdt(); + MG_DEBUG(("esp_ota_begin(): %d", err)); + s_ota_success = (err == ESP_OK); + } + return s_ota_success; +} + +bool mg_ota_write(const void *buf, size_t len) { + disable_wdt(); + esp_err_t err = esp_ota_write(s_ota_update_handle, buf, len); + enable_wdt(); + MG_INFO(("esp_ota_write(): %d", err)); + s_ota_success = err == ESP_OK; + return s_ota_success; +} + +bool mg_ota_end(void) { + esp_err_t err = esp_ota_end(s_ota_update_handle); + MG_DEBUG(("esp_ota_end(%p): %d", s_ota_update_handle, err)); + if (s_ota_success && err == ESP_OK) { + err = esp_ota_set_boot_partition(s_ota_update_partition); + s_ota_success = (err == ESP_OK); + } + MG_DEBUG(("Finished ESP32 OTA, success: %d", s_ota_success)); + s_ota_update_partition = NULL; + return s_ota_success; +} + +#endif + #ifdef MG_ENABLE_LINES #line 1 "src/ota_flash.c" #endif diff --git a/mongoose.h b/mongoose.h index 9b2813f1..519352a6 100644 --- a/mongoose.h +++ b/mongoose.h @@ -120,7 +120,8 @@ extern "C" { #include #include -#include +#include // Use angle brackets to avoid +#include // amalgamation ditching them #define MG_PATH_MAX 128 @@ -2484,6 +2485,7 @@ void mg_rpc_list(struct mg_rpc_req *r); #define MG_OTA_NONE 0 // No OTA support #define MG_OTA_FLASH 1 // OTA via an internal flash +#define MG_OTA_ESP32 2 // ESP32 OTA implementation #define MG_OTA_CUSTOM 100 // Custom implementation #ifndef MG_OTA @@ -2524,13 +2526,14 @@ MG_IRAM void mg_ota_boot(void); // Bootloader function -#define MG_DEVICE_NONE 0 // Dummy system +#define MG_DEVICE_NONE 0 // Dummy system + #define MG_DEVICE_STM32H5 1 // STM32 H5 #define MG_DEVICE_STM32H7 2 // STM32 H7 -#define MG_DEVICE_RT1020 3 // IMXRT1020 -#define MG_DEVICE_RT1060 4 // IMXRT1060 #define MG_DEVICE_CH32V307 100 // WCH CH32V307 #define MG_DEVICE_U2A 200 // Renesas U2A16, U2A8, U2A6 +#define MG_DEVICE_RT1020 300 // IMXRT1020 +#define MG_DEVICE_RT1060 301 // IMXRT1060 #define MG_DEVICE_CUSTOM 1000 // Custom implementation #ifndef MG_DEVICE @@ -2922,14 +2925,6 @@ struct mg_tcpip_driver_tm4c_data { #endif -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500 - -#undef MG_ENABLE_TCPIP_DRIVER_INIT -#define MG_ENABLE_TCPIP_DRIVER_INIT 0 - -#endif - - #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { diff --git a/src/arch_esp32.h b/src/arch_esp32.h index 2aade7be..ea30ec5d 100644 --- a/src/arch_esp32.h +++ b/src/arch_esp32.h @@ -17,7 +17,8 @@ #include #include -#include +#include // Use angle brackets to avoid +#include // amalgamation ditching them #define MG_PATH_MAX 128 diff --git a/src/device.h b/src/device.h index d90b82da..187a79d6 100644 --- a/src/device.h +++ b/src/device.h @@ -5,13 +5,14 @@ #include "arch.h" -#define MG_DEVICE_NONE 0 // Dummy system +#define MG_DEVICE_NONE 0 // Dummy system + #define MG_DEVICE_STM32H5 1 // STM32 H5 #define MG_DEVICE_STM32H7 2 // STM32 H7 -#define MG_DEVICE_RT1020 3 // IMXRT1020 -#define MG_DEVICE_RT1060 4 // IMXRT1060 #define MG_DEVICE_CH32V307 100 // WCH CH32V307 #define MG_DEVICE_U2A 200 // Renesas U2A16, U2A8, U2A6 +#define MG_DEVICE_RT1020 300 // IMXRT1020 +#define MG_DEVICE_RT1060 301 // IMXRT1060 #define MG_DEVICE_CUSTOM 1000 // Custom implementation #ifndef MG_DEVICE diff --git a/src/ota.h b/src/ota.h index d9b25990..5109fc60 100644 --- a/src/ota.h +++ b/src/ota.h @@ -7,6 +7,7 @@ #define MG_OTA_NONE 0 // No OTA support #define MG_OTA_FLASH 1 // OTA via an internal flash +#define MG_OTA_ESP32 2 // ESP32 OTA implementation #define MG_OTA_CUSTOM 100 // Custom implementation #ifndef MG_OTA diff --git a/src/ota_esp32.c b/src/ota_esp32.c new file mode 100644 index 00000000..d437d620 --- /dev/null +++ b/src/ota_esp32.c @@ -0,0 +1,52 @@ +#include "arch.h" + +#if MG_ARCH == MG_ARCH_ESP32 && MG_OTA == MG_OTA_ESP32 + +static const esp_partition_t *s_ota_update_partition; +static esp_ota_handle_t s_ota_update_handle; +static bool s_ota_success; + +// Those empty macros do nothing, but mark places in the code which could +// potentially trigger a watchdog reboot due to the log flash erase operation +#define disable_wdt() +#define enable_wdt() + +bool mg_ota_begin(size_t new_firmware_size) { + if (s_ota_update_partition != NULL) { + MG_ERROR(("Update in progress. Call mg_ota_end() ?")); + return false; + } else { + s_ota_success = false; + disable_wdt(); + s_ota_update_partition = esp_ota_get_next_update_partition(NULL); + esp_err_t err = esp_ota_begin(s_ota_update_partition, new_firmware_size, + &s_ota_update_handle); + enable_wdt(); + MG_DEBUG(("esp_ota_begin(): %d", err)); + s_ota_success = (err == ESP_OK); + } + return s_ota_success; +} + +bool mg_ota_write(const void *buf, size_t len) { + disable_wdt(); + esp_err_t err = esp_ota_write(s_ota_update_handle, buf, len); + enable_wdt(); + MG_INFO(("esp_ota_write(): %d", err)); + s_ota_success = err == ESP_OK; + return s_ota_success; +} + +bool mg_ota_end(void) { + esp_err_t err = esp_ota_end(s_ota_update_handle); + MG_DEBUG(("esp_ota_end(%p): %d", s_ota_update_handle, err)); + if (s_ota_success && err == ESP_OK) { + err = esp_ota_set_boot_partition(s_ota_update_partition); + s_ota_success = (err == ESP_OK); + } + MG_DEBUG(("Finished ESP32 OTA, success: %d", s_ota_success)); + s_ota_update_partition = NULL; + return s_ota_success; +} + +#endif