From 61f03292faa4a10be5b90402d74a2d6b3f822846 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 20 Nov 2025 14:20:07 +0200 Subject: [PATCH 1/6] feat(hosted): Implement OTA for esp-hosted co-processors --- cores/esp32/esp32-hal-hosted.c | 70 ++++++++++-- .../examples/ESP_HostedOTA/ESP_HostedOTA.ino | 37 +++++++ libraries/ESP_HostedOTA/keywords.txt | 17 +++ libraries/ESP_HostedOTA/library.properties | 9 ++ libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp | 104 ++++++++++++++++++ libraries/ESP_HostedOTA/src/ESP_HostedOTA.h | 5 + 6 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino create mode 100644 libraries/ESP_HostedOTA/keywords.txt create mode 100644 libraries/ESP_HostedOTA/library.properties create mode 100644 libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp create mode 100644 libraries/ESP_HostedOTA/src/ESP_HostedOTA.h diff --git a/cores/esp32/esp32-hal-hosted.c b/cores/esp32/esp32-hal-hosted.c index 4fba105457c..9d39a7a24e7 100644 --- a/cores/esp32/esp32-hal-hosted.c +++ b/cores/esp32/esp32-hal-hosted.c @@ -17,6 +17,7 @@ #include "esp32-hal-hosted.h" #include "esp32-hal-log.h" +#include "esp32-hal.h" #include "pins_arduino.h" #include "esp_hosted.h" @@ -53,6 +54,9 @@ static esp_hosted_coprocessor_fwver_t host_version_struct = { .major1 = ESP_HOSTED_VERSION_MAJOR_1, .minor1 = ESP_HOSTED_VERSION_MINOR_1, .patch1 = ESP_HOSTED_VERSION_PATCH_1 }; +static bool hostedInit(); +static bool hostedDeinit(); + void hostedGetHostVersion(uint32_t *major, uint32_t *minor, uint32_t *patch) { *major = host_version_struct.major1; *minor = host_version_struct.minor1; @@ -66,6 +70,11 @@ void hostedGetSlaveVersion(uint32_t *major, uint32_t *minor, uint32_t *patch) { } bool hostedHasUpdate() { + if (!hosted_initialized) { + log_e("ESP-Hosted is not initialized"); + return false; + } + uint32_t host_version = ESP_HOSTED_VERSION_VAL(host_version_struct.major1, host_version_struct.minor1, host_version_struct.patch1); uint32_t slave_version = 0; @@ -106,6 +115,11 @@ char *hostedGetUpdateURL() { } bool hostedBeginUpdate() { + if (!hosted_initialized) { + log_e("ESP-Hosted is not initialized"); + return false; + } + esp_err_t err = esp_hosted_slave_ota_begin(); if (err != ESP_OK) { log_e("Failed to begin Update: %s", esp_err_to_name(err)); @@ -114,6 +128,11 @@ bool hostedBeginUpdate() { } bool hostedWriteUpdate(uint8_t *buf, uint32_t len) { + if (!hosted_initialized) { + log_e("ESP-Hosted is not initialized"); + return false; + } + esp_err_t err = esp_hosted_slave_ota_write(buf, len); if (err != ESP_OK) { log_e("Failed to write Update: %s", esp_err_to_name(err)); @@ -122,6 +141,11 @@ bool hostedWriteUpdate(uint8_t *buf, uint32_t len) { } bool hostedEndUpdate() { + if (!hosted_initialized) { + log_e("ESP-Hosted is not initialized"); + return false; + } + esp_err_t err = esp_hosted_slave_ota_end(); if (err != ESP_OK) { log_e("Failed to end Update: %s", esp_err_to_name(err)); @@ -130,16 +154,31 @@ bool hostedEndUpdate() { } bool hostedActivateUpdate() { + if (!hosted_initialized) { + log_e("ESP-Hosted is not initialized"); + return false; + } + + // Activate can fail on older firmwares and that is not critical + uint32_t slave_version = ESP_HOSTED_VERSION_VAL(slave_version_struct.major1, slave_version_struct.minor1, slave_version_struct.patch1); + uint32_t min_version = ESP_HOSTED_VERSION_VAL(2, 6, 0); + + if (slave_version < min_version) { + // Silence messages caused by earlier versions + esp_log_level_set("rpc_core", ESP_LOG_NONE); + } + esp_err_t err = esp_hosted_slave_ota_activate(); - if (err != ESP_OK) { + + // Any further communication will result in logged errors + esp_log_level_set("sdmmc_io", ESP_LOG_NONE); + esp_log_level_set("H_SDIO_DRV", ESP_LOG_NONE); + + if (err != ESP_OK && slave_version >= min_version) { log_e("Failed to activate Update: %s", esp_err_to_name(err)); + return false; } - // else { - // hostedDeinit(); - // delay(1000); - // hostedInit(); - // } - return err == ESP_OK; + return true; } static bool hostedInit() { @@ -158,15 +197,22 @@ static bool hostedInit() { conf.pin_d2.pin = sdio_pin_config.pin_d2; conf.pin_d3.pin = sdio_pin_config.pin_d3; conf.pin_reset.pin = sdio_pin_config.pin_reset; - // esp_hosted_sdio_set_config() will fail on second attempt but here temporarily to not cause exception on reinit - if (esp_hosted_sdio_set_config(&conf) != ESP_OK || esp_hosted_init() != ESP_OK) { - log_e("esp_hosted_init failed!"); + esp_err_t err = esp_hosted_sdio_set_config(&conf); + if (err != ESP_OK) { //&& err != ESP_ERR_NOT_ALLOWED) { // uncomment when second init is fixed + log_e("esp_hosted_sdio_set_config failed: %s", esp_err_to_name(err)); + return false; + } + err = esp_hosted_init(); + if (err != ESP_OK) { + log_e("esp_hosted_init failed: %s", esp_err_to_name(err)); hosted_initialized = false; return false; } log_i("ESP-Hosted initialized!"); - if (esp_hosted_connect_to_slave() != ESP_OK) { - log_e("Failed to connect to slave"); + err = esp_hosted_connect_to_slave(); + if (err != ESP_OK) { + log_e("esp_hosted_connect_to_slave failed: %s", esp_err_to_name(err)); + hosted_initialized = false; return false; } hostedHasUpdate(); diff --git a/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino new file mode 100644 index 00000000000..041e139079d --- /dev/null +++ b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino @@ -0,0 +1,37 @@ +#include "WiFi.h" +#include "ESP_HostedOTA.h" + +const char *ssid = "your-ssid"; // Change this to your WiFi SSID +const char *password = "your-password"; // Change this to your WiFi password + +void setup() { + Serial.begin(115200); + + WiFi.STA.begin(); + + Serial.println(); + Serial.println("******************************************************"); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.STA.connect(ssid, password); + + while (WiFi.STA.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.STA.localIP()); + + if (updateEspHostedSlave()) { + // Currently it's required to restart the host + ESP.restart(); + } +} + +void loop() { + delay(1000); +} diff --git a/libraries/ESP_HostedOTA/keywords.txt b/libraries/ESP_HostedOTA/keywords.txt new file mode 100644 index 00000000000..f34de27a296 --- /dev/null +++ b/libraries/ESP_HostedOTA/keywords.txt @@ -0,0 +1,17 @@ +####################################### +# Syntax Coloring Map For ESP_HostedOTA +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +updateEspHostedSlave KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/ESP_HostedOTA/library.properties b/libraries/ESP_HostedOTA/library.properties new file mode 100644 index 00000000000..a45ab7aa138 --- /dev/null +++ b/libraries/ESP_HostedOTA/library.properties @@ -0,0 +1,9 @@ +name=ESP_HostedOTA +version=3.3.4 +author=me-no-dev +maintainer=me-no-dev +sentence=Library for updating the ESP-Hosted co-processor +paragraph=Supports ESP32 Arduino platforms. +category=Communication +url=https://github.com/espressif/arduino-esp32/ +architectures=esp32 diff --git a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp new file mode 100644 index 00000000000..32e0b19c700 --- /dev/null +++ b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp @@ -0,0 +1,104 @@ +#include "sdkconfig.h" +#if CONFIG_ESP_WIFI_REMOTE_ENABLED +#include "Arduino.h" +#include "esp32-hal-hosted.h" +#include "Network.h" +#include "HTTPClient.h" +#include "NetworkClientSecure.h" +#endif + +bool updateEspHostedSlave() { +#if CONFIG_ESP_WIFI_REMOTE_ENABLED + bool updateSuccess = false; + if (!hostedIsInitialized()) { + Serial.println("ERROR: esp-hosted is not initialized. Did you call WiFi.STA.begin()?"); + return updateSuccess; + } + if (!hostedHasUpdate()) { + // esp-hosted is already the latest version + return updateSuccess; + } + if (!Network.isOnline()) { + Serial.println("ERROR: Network is not online! Did you call WiFi.STA.connect(ssid, password)?"); + return updateSuccess; + } + Serial.print("Updating esp-hosted co-processor from "); + Serial.println(hostedGetUpdateURL()); + NetworkClientSecure *client = new NetworkClientSecure(); + if (!client) { + Serial.println("ERROR: Could not allocate client!"); + return updateSuccess; + } + client->setInsecure(); + HTTPClient https; + int httpCode = 0; + if (!https.begin(*client, hostedGetUpdateURL())) { + Serial.println("ERROR: HTTP begin failed!"); + goto finish_ota; + } + httpCode = https.GET(); + if (httpCode == HTTP_CODE_OK) { + int len = https.getSize(); + if (len < 0) { + Serial.println("ERROR: Update size not received!"); + https.end(); + goto finish_ota; + } + NetworkClient *stream = https.getStreamPtr(); + if (!hostedBeginUpdate()) { + Serial.println("ERROR: esp-hosted update start failed!"); + https.end(); + goto finish_ota; + } + #define HOSTED_OTA_BUF_SIZE 2048 + uint8_t * buff = (uint8_t*)malloc(HOSTED_OTA_BUF_SIZE); + if (!buff) { + Serial.println("ERROR: Could not allocate OTA buffer!"); + https.end(); + goto finish_ota; + } + while (https.connected() && len > 0) { + size_t size = stream->available(); + if (size > 0) { + Serial.print("."); + if (size > HOSTED_OTA_BUF_SIZE) { + size = HOSTED_OTA_BUF_SIZE; + } + if (size > len) { + Serial.printf("\nERROR: Update received extra bytes: %u!", size - len); + break; + } + int readLen = stream->readBytes(buff, size); + len -= readLen; + if (!hostedWriteUpdate(buff, readLen)) { + Serial.println("\nERROR: esp-hosted update write failed!"); + break; + } + if (len == 0) { + if (!hostedEndUpdate()) { + Serial.println("\nERROR: esp-hosted update end failed!"); + break; + } + if (!hostedActivateUpdate()) { + Serial.println("\nERROR: esp-hosted update activate failed!"); + break; + } + updateSuccess = true; + Serial.println("\nSUCCESS: esp-hosted co-processor updated!"); + break; + } + } + delay(1); + } + free(buff); + Serial.println(); + } + + https.end(); +finish_ota: + delete client; + return updateSuccess; +#else + return false; +#endif +} diff --git a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h new file mode 100644 index 00000000000..d4f5e7a89f9 --- /dev/null +++ b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +bool updateEspHostedSlave(); From c084de98dfe62ae03f27f97eaa3f1c1f550cf124 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 25 Nov 2025 15:29:33 +0200 Subject: [PATCH 2/6] feat(hosted): Add library to CMakeLists.txt --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9b295dfa70..4732354aa73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,7 @@ set(ARDUINO_ALL_LIBRARIES ESP_I2S ESP_NOW ESP_SR + ESP_HostedOTA ESPmDNS Ethernet FFat @@ -146,6 +147,9 @@ set(ARDUINO_LIBRARY_ESP_SR_SRCS libraries/ESP_SR/src/ESP_SR.cpp libraries/ESP_SR/src/esp32-hal-sr.c) +set(ARDUINO_LIBRARY_ESP_HostedOTA_SRCS + libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp) + set(ARDUINO_LIBRARY_ESPmDNS_SRCS libraries/ESPmDNS/src/ESPmDNS.cpp) set(ARDUINO_LIBRARY_Ethernet_SRCS libraries/Ethernet/src/ETH.cpp) From 0a950ccd4e276f627a1c165cd44efcaea08db5f5 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 25 Nov 2025 16:58:04 +0200 Subject: [PATCH 3/6] feat(hosted): Limit CI to run the example only on P4 --- libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ci.yml | 2 ++ libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp | 1 + 2 files changed, 3 insertions(+) create mode 100644 libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ci.yml diff --git a/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ci.yml b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ci.yml new file mode 100644 index 00000000000..8548a039255 --- /dev/null +++ b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ci.yml @@ -0,0 +1,2 @@ +requires: + - CONFIG_ESP_WIFI_REMOTE_ENABLED=y diff --git a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp index 32e0b19c700..f6b1d84dcdb 100644 --- a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp +++ b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp @@ -1,4 +1,5 @@ #include "sdkconfig.h" +#include #if CONFIG_ESP_WIFI_REMOTE_ENABLED #include "Arduino.h" #include "esp32-hal-hosted.h" From 5ebe76d08d83eb9c8db579f53a4b877b2656be57 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 27 Nov 2025 02:41:39 +0200 Subject: [PATCH 4/6] feat(hosted): Document inline the source code --- .../examples/ESP_HostedOTA/ESP_HostedOTA.ino | 43 +++++++++++-- libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp | 64 +++++++++++++++++-- libraries/ESP_HostedOTA/src/ESP_HostedOTA.h | 5 ++ 3 files changed, 100 insertions(+), 12 deletions(-) diff --git a/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino index 041e139079d..6c981e0c1c9 100644 --- a/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino +++ b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino @@ -1,33 +1,62 @@ -#include "WiFi.h" -#include "ESP_HostedOTA.h" +/* + * ESP-Hosted OTA Update Example + * + * This example demonstrates how to update the ESP-Hosted co-processor firmware + * over-the-air (OTA). The ESP-Hosted solution allows an ESP32 to act as a WiFi + * co-processor for other microcontrollers. + * + * Prerequisites: + * - ESP32 with ESP-Hosted firmware configured as WiFi co-processor + * - Network connectivity to download firmware updates + * - Valid WiFi credentials + */ -const char *ssid = "your-ssid"; // Change this to your WiFi SSID -const char *password = "your-password"; // Change this to your WiFi password +#include "WiFi.h" // WiFi library for network connectivity +#include "ESP_HostedOTA.h" // ESP-Hosted OTA update functionality + +// WiFi network credentials - CHANGE THESE TO YOUR NETWORK SETTINGS +const char *ssid = "your-ssid"; // Replace with your WiFi network name +const char *password = "your-password"; // Replace with your WiFi password void setup() { + // Step 1: Initialize serial communication for debugging output Serial.begin(115200); + // Step 2: Initialize the ESP-Hosted WiFi station mode + // This prepares the ESP-Hosted co-processor for WiFi operations WiFi.STA.begin(); + // Step 3: Display connection attempt information Serial.println(); Serial.println("******************************************************"); Serial.print("Connecting to "); Serial.println(ssid); + // Step 4: Attempt to connect to the specified WiFi network WiFi.STA.connect(ssid, password); + // Step 5: Wait for WiFi connection to be established + // Display progress dots while connecting while (WiFi.STA.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); + delay(500); // Wait 500ms between connection attempts + Serial.print("."); // Show connection progress } Serial.println(); + // Step 6: Display successful connection information Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.STA.localIP()); + // Step 7: Attempt to update the ESP-Hosted co-processor firmware + // This function will: + // - Check if ESP-Hosted is initialized + // - Verify if an update is available + // - Download and install the firmware update if needed if (updateEspHostedSlave()) { - // Currently it's required to restart the host + // Step 8: Restart the host ESP32 after successful update + // This is currently required to properly activate the new firmware + // on the ESP-Hosted co-processor ESP.restart(); } } diff --git a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp index f6b1d84dcdb..5d075809520 100644 --- a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp +++ b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp @@ -1,56 +1,85 @@ +// Include necessary headers for SDK configuration, Arduino framework, and networking #include "sdkconfig.h" #include #if CONFIG_ESP_WIFI_REMOTE_ENABLED #include "Arduino.h" -#include "esp32-hal-hosted.h" -#include "Network.h" -#include "HTTPClient.h" -#include "NetworkClientSecure.h" +#include "esp32-hal-hosted.h" // ESP-Hosted specific functions +#include "Network.h" // Network connectivity management +#include "HTTPClient.h" // HTTP client for downloading updates +#include "NetworkClientSecure.h" // Secure network client for HTTPS #endif +/** + * Updates the ESP-Hosted co-processor firmware over-the-air (OTA) + * This function downloads and installs firmware updates for the ESP-Hosted slave device + * @return true if update was successful, false otherwise + */ bool updateEspHostedSlave() { #if CONFIG_ESP_WIFI_REMOTE_ENABLED bool updateSuccess = false; + + // Step 1: Verify ESP-Hosted is properly initialized if (!hostedIsInitialized()) { Serial.println("ERROR: esp-hosted is not initialized. Did you call WiFi.STA.begin()?"); return updateSuccess; } + + // Step 2: Check if an update is actually available if (!hostedHasUpdate()) { - // esp-hosted is already the latest version + // esp-hosted is already the latest version - no update needed return updateSuccess; } + + // Step 3: Ensure network connectivity is available if (!Network.isOnline()) { Serial.println("ERROR: Network is not online! Did you call WiFi.STA.connect(ssid, password)?"); return updateSuccess; } + + // Step 4: Begin the update process - display update URL Serial.print("Updating esp-hosted co-processor from "); Serial.println(hostedGetUpdateURL()); + + // Step 5: Create a secure network client for HTTPS communication NetworkClientSecure *client = new NetworkClientSecure(); if (!client) { Serial.println("ERROR: Could not allocate client!"); return updateSuccess; } + + // Step 6: Configure client to skip certificate verification (insecure mode) client->setInsecure(); + + // Step 7: Initialize HTTP client and attempt to connect to update server HTTPClient https; int httpCode = 0; if (!https.begin(*client, hostedGetUpdateURL())) { Serial.println("ERROR: HTTP begin failed!"); goto finish_ota; } + + // Step 8: Send HTTP GET request to download the firmware httpCode = https.GET(); if (httpCode == HTTP_CODE_OK) { + // Step 9: Get the size of the firmware file to download int len = https.getSize(); if (len < 0) { Serial.println("ERROR: Update size not received!"); https.end(); goto finish_ota; } + + // Step 10: Get stream pointer for reading firmware data NetworkClient *stream = https.getStreamPtr(); + + // Step 11: Initialize the ESP-Hosted update process if (!hostedBeginUpdate()) { Serial.println("ERROR: esp-hosted update start failed!"); https.end(); goto finish_ota; } + + // Step 12: Allocate buffer for firmware data transfer (2KB chunks) #define HOSTED_OTA_BUF_SIZE 2048 uint8_t * buff = (uint8_t*)malloc(HOSTED_OTA_BUF_SIZE); if (!buff) { @@ -58,48 +87,73 @@ bool updateEspHostedSlave() { https.end(); goto finish_ota; } + + // Step 13: Download and write firmware data in chunks while (https.connected() && len > 0) { size_t size = stream->available(); if (size > 0) { + // Show progress indicator Serial.print("."); + + // Limit chunk size to buffer capacity if (size > HOSTED_OTA_BUF_SIZE) { size = HOSTED_OTA_BUF_SIZE; } + + // Prevent reading more data than expected if (size > len) { Serial.printf("\nERROR: Update received extra bytes: %u!", size - len); break; } + + // Read firmware data chunk into buffer int readLen = stream->readBytes(buff, size); len -= readLen; + + // Write the chunk to ESP-Hosted co-processor if (!hostedWriteUpdate(buff, readLen)) { Serial.println("\nERROR: esp-hosted update write failed!"); break; } + + // Step 14: Check if entire firmware has been downloaded if (len == 0) { + // Finalize the update process if (!hostedEndUpdate()) { Serial.println("\nERROR: esp-hosted update end failed!"); break; } + + // Activate the new firmware if (!hostedActivateUpdate()) { Serial.println("\nERROR: esp-hosted update activate failed!"); break; } + + // Update completed successfully updateSuccess = true; Serial.println("\nSUCCESS: esp-hosted co-processor updated!"); break; } } + // Small delay to prevent overwhelming the system delay(1); } + + // Step 15: Clean up allocated buffer free(buff); Serial.println(); } + // Step 16: Close HTTP connection https.end(); + finish_ota: + // Step 17: Clean up network client delete client; return updateSuccess; #else + // ESP-Hosted functionality is not enabled in SDK configuration return false; #endif } diff --git a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h index d4f5e7a89f9..56c35ec2b07 100644 --- a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h +++ b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.h @@ -2,4 +2,9 @@ #include +/** + * Updates the ESP-Hosted co-processor firmware over-the-air (OTA) + * This function downloads and installs firmware updates for the ESP-Hosted slave device + * @return true if update was successful, false otherwise + */ bool updateEspHostedSlave(); From a37aebbafff9300c48c771116f850fe9a7bc52e1 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 1 Dec 2025 14:00:24 +0200 Subject: [PATCH 5/6] feat(hosted): Add library to code owners --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bd18f7ad973..eff3343620c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -54,6 +54,7 @@ /libraries/ArduinoOTA/ @me-no-dev /libraries/AsyncUDP/ @me-no-dev /libraries/BLE/ @lucasssvaz @SuGlider +/libraries/ESP_HostedOTA/ @me-no-dev /libraries/ESP_I2S/ @me-no-dev /libraries/ESP_NOW/ @P-R-O-C-H-Y @lucasssvaz /libraries/ESP_SR/ @me-no-dev From 011b4ededf2d8077e79f8286fa00b44634d09aa0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:01:54 +0000 Subject: [PATCH 6/6] ci(pre-commit): Apply automatic fixes --- cores/esp32/esp32-hal-hosted.c | 2 +- .../examples/ESP_HostedOTA/ESP_HostedOTA.ino | 8 +-- libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp | 56 +++++++++---------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/cores/esp32/esp32-hal-hosted.c b/cores/esp32/esp32-hal-hosted.c index 9d39a7a24e7..b5ab854dbc8 100644 --- a/cores/esp32/esp32-hal-hosted.c +++ b/cores/esp32/esp32-hal-hosted.c @@ -198,7 +198,7 @@ static bool hostedInit() { conf.pin_d3.pin = sdio_pin_config.pin_d3; conf.pin_reset.pin = sdio_pin_config.pin_reset; esp_err_t err = esp_hosted_sdio_set_config(&conf); - if (err != ESP_OK) { //&& err != ESP_ERR_NOT_ALLOWED) { // uncomment when second init is fixed + if (err != ESP_OK) { //&& err != ESP_ERR_NOT_ALLOWED) { // uncomment when second init is fixed log_e("esp_hosted_sdio_set_config failed: %s", esp_err_to_name(err)); return false; } diff --git a/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino index 6c981e0c1c9..01c40d5cebd 100644 --- a/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino +++ b/libraries/ESP_HostedOTA/examples/ESP_HostedOTA/ESP_HostedOTA.ino @@ -1,10 +1,10 @@ /* * ESP-Hosted OTA Update Example - * + * * This example demonstrates how to update the ESP-Hosted co-processor firmware * over-the-air (OTA). The ESP-Hosted solution allows an ESP32 to act as a WiFi * co-processor for other microcontrollers. - * + * * Prerequisites: * - ESP32 with ESP-Hosted firmware configured as WiFi co-processor * - Network connectivity to download firmware updates @@ -38,8 +38,8 @@ void setup() { // Step 5: Wait for WiFi connection to be established // Display progress dots while connecting while (WiFi.STA.status() != WL_CONNECTED) { - delay(500); // Wait 500ms between connection attempts - Serial.print("."); // Show connection progress + delay(500); // Wait 500ms between connection attempts + Serial.print("."); // Show connection progress } Serial.println(); diff --git a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp index 5d075809520..33b2f957419 100644 --- a/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp +++ b/libraries/ESP_HostedOTA/src/ESP_HostedOTA.cpp @@ -3,10 +3,10 @@ #include #if CONFIG_ESP_WIFI_REMOTE_ENABLED #include "Arduino.h" -#include "esp32-hal-hosted.h" // ESP-Hosted specific functions -#include "Network.h" // Network connectivity management -#include "HTTPClient.h" // HTTP client for downloading updates -#include "NetworkClientSecure.h" // Secure network client for HTTPS +#include "esp32-hal-hosted.h" // ESP-Hosted specific functions +#include "Network.h" // Network connectivity management +#include "HTTPClient.h" // HTTP client for downloading updates +#include "NetworkClientSecure.h" // Secure network client for HTTPS #endif /** @@ -17,39 +17,39 @@ bool updateEspHostedSlave() { #if CONFIG_ESP_WIFI_REMOTE_ENABLED bool updateSuccess = false; - + // Step 1: Verify ESP-Hosted is properly initialized if (!hostedIsInitialized()) { Serial.println("ERROR: esp-hosted is not initialized. Did you call WiFi.STA.begin()?"); return updateSuccess; } - + // Step 2: Check if an update is actually available if (!hostedHasUpdate()) { // esp-hosted is already the latest version - no update needed return updateSuccess; } - + // Step 3: Ensure network connectivity is available if (!Network.isOnline()) { Serial.println("ERROR: Network is not online! Did you call WiFi.STA.connect(ssid, password)?"); return updateSuccess; } - + // Step 4: Begin the update process - display update URL Serial.print("Updating esp-hosted co-processor from "); Serial.println(hostedGetUpdateURL()); - + // Step 5: Create a secure network client for HTTPS communication NetworkClientSecure *client = new NetworkClientSecure(); if (!client) { Serial.println("ERROR: Could not allocate client!"); return updateSuccess; } - + // Step 6: Configure client to skip certificate verification (insecure mode) client->setInsecure(); - + // Step 7: Initialize HTTP client and attempt to connect to update server HTTPClient https; int httpCode = 0; @@ -57,7 +57,7 @@ bool updateEspHostedSlave() { Serial.println("ERROR: HTTP begin failed!"); goto finish_ota; } - + // Step 8: Send HTTP GET request to download the firmware httpCode = https.GET(); if (httpCode == HTTP_CODE_OK) { @@ -68,54 +68,54 @@ bool updateEspHostedSlave() { https.end(); goto finish_ota; } - + // Step 10: Get stream pointer for reading firmware data NetworkClient *stream = https.getStreamPtr(); - + // Step 11: Initialize the ESP-Hosted update process if (!hostedBeginUpdate()) { Serial.println("ERROR: esp-hosted update start failed!"); https.end(); goto finish_ota; } - - // Step 12: Allocate buffer for firmware data transfer (2KB chunks) - #define HOSTED_OTA_BUF_SIZE 2048 - uint8_t * buff = (uint8_t*)malloc(HOSTED_OTA_BUF_SIZE); + +// Step 12: Allocate buffer for firmware data transfer (2KB chunks) +#define HOSTED_OTA_BUF_SIZE 2048 + uint8_t *buff = (uint8_t *)malloc(HOSTED_OTA_BUF_SIZE); if (!buff) { Serial.println("ERROR: Could not allocate OTA buffer!"); https.end(); goto finish_ota; } - + // Step 13: Download and write firmware data in chunks while (https.connected() && len > 0) { size_t size = stream->available(); if (size > 0) { // Show progress indicator Serial.print("."); - + // Limit chunk size to buffer capacity if (size > HOSTED_OTA_BUF_SIZE) { size = HOSTED_OTA_BUF_SIZE; } - + // Prevent reading more data than expected if (size > len) { Serial.printf("\nERROR: Update received extra bytes: %u!", size - len); break; } - + // Read firmware data chunk into buffer int readLen = stream->readBytes(buff, size); len -= readLen; - + // Write the chunk to ESP-Hosted co-processor if (!hostedWriteUpdate(buff, readLen)) { Serial.println("\nERROR: esp-hosted update write failed!"); break; } - + // Step 14: Check if entire firmware has been downloaded if (len == 0) { // Finalize the update process @@ -123,13 +123,13 @@ bool updateEspHostedSlave() { Serial.println("\nERROR: esp-hosted update end failed!"); break; } - + // Activate the new firmware if (!hostedActivateUpdate()) { Serial.println("\nERROR: esp-hosted update activate failed!"); break; } - + // Update completed successfully updateSuccess = true; Serial.println("\nSUCCESS: esp-hosted co-processor updated!"); @@ -139,7 +139,7 @@ bool updateEspHostedSlave() { // Small delay to prevent overwhelming the system delay(1); } - + // Step 15: Clean up allocated buffer free(buff); Serial.println(); @@ -147,7 +147,7 @@ bool updateEspHostedSlave() { // Step 16: Close HTTP connection https.end(); - + finish_ota: // Step 17: Clean up network client delete client;