diff --git a/esphome/components/esp8266/__init__.py b/esphome/components/esp8266/__init__.py index a74f9ee8ce..c4969a79b2 100644 --- a/esphome/components/esp8266/__init__.py +++ b/esphome/components/esp8266/__init__.py @@ -191,7 +191,8 @@ async def to_code(config): cg.add_define(ThreadModel.SINGLE) cg.add_platformio_option( - "extra_scripts", ["pre:testing_mode.py", "post:post_build.py"] + "extra_scripts", + ["pre:testing_mode.py", "pre:exclude_updater.py", "post:post_build.py"], ) conf = config[CONF_FRAMEWORK] @@ -278,3 +279,8 @@ def copy_files(): testing_mode_file, CORE.relative_build_path("testing_mode.py"), ) + exclude_updater_file = dir / "exclude_updater.py.script" + copy_file_if_changed( + exclude_updater_file, + CORE.relative_build_path("exclude_updater.py"), + ) diff --git a/esphome/components/esp8266/exclude_updater.py.script b/esphome/components/esp8266/exclude_updater.py.script new file mode 100644 index 0000000000..69331e3b03 --- /dev/null +++ b/esphome/components/esp8266/exclude_updater.py.script @@ -0,0 +1,21 @@ +# pylint: disable=E0602 +Import("env") # noqa + +import os + +# Filter out Updater.cpp from the Arduino core build +# This saves 228 bytes of .bss by not instantiating the global Update object +# ESPHome uses its own native OTA backend instead + + +def filter_updater_from_core(env, node): + """Filter callback to exclude Updater.cpp from framework build.""" + path = node.get_path() + if path.endswith("Updater.cpp"): + print(f"ESPHome: Excluding {os.path.basename(path)} from build (using native OTA backend)") + return None + return node + + +# Apply the filter to framework sources +env.AddBuildMiddleware(filter_updater_from_core, "**/cores/esp8266/Updater.cpp") diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index b589a6119f..f9984e1425 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -10,7 +10,7 @@ #endif #include "esphome/components/network/util.h" #include "esphome/components/ota/ota_backend.h" -#include "esphome/components/ota/ota_backend_arduino_esp8266.h" +#include "esphome/components/ota/ota_backend_esp8266.h" #include "esphome/components/ota/ota_backend_arduino_libretiny.h" #include "esphome/components/ota/ota_backend_arduino_rp2040.h" #include "esphome/components/ota/ota_backend_esp_idf.h" diff --git a/esphome/components/http_request/ota/ota_http_request.cpp b/esphome/components/http_request/ota/ota_http_request.cpp index 058579752e..2cd7489e38 100644 --- a/esphome/components/http_request/ota/ota_http_request.cpp +++ b/esphome/components/http_request/ota/ota_http_request.cpp @@ -7,7 +7,7 @@ #include "esphome/components/md5/md5.h" #include "esphome/components/watchdog/watchdog.h" #include "esphome/components/ota/ota_backend.h" -#include "esphome/components/ota/ota_backend_arduino_esp8266.h" +#include "esphome/components/ota/ota_backend_esp8266.h" #include "esphome/components/ota/ota_backend_arduino_rp2040.h" #include "esphome/components/ota/ota_backend_esp_idf.h" diff --git a/esphome/components/ota/__init__.py b/esphome/components/ota/__init__.py index 8bed9cee42..a514a7482f 100644 --- a/esphome/components/ota/__init__.py +++ b/esphome/components/ota/__init__.py @@ -148,7 +148,7 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform( PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF, }, - "ota_backend_arduino_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "ota_backend_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, "ota_backend_arduino_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, "ota_backend_arduino_libretiny.cpp": { PlatformFramework.BK72XX_ARDUINO, diff --git a/esphome/components/ota/ota_backend_arduino_esp8266.cpp b/esphome/components/ota/ota_backend_arduino_esp8266.cpp deleted file mode 100644 index 375c4e7200..0000000000 --- a/esphome/components/ota/ota_backend_arduino_esp8266.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#ifdef USE_ARDUINO -#ifdef USE_ESP8266 -#include "ota_backend_arduino_esp8266.h" -#include "ota_backend.h" - -#include "esphome/components/esp8266/preferences.h" -#include "esphome/core/defines.h" -#include "esphome/core/log.h" - -#include - -namespace esphome { -namespace ota { - -static const char *const TAG = "ota.arduino_esp8266"; - -std::unique_ptr make_ota_backend() { return make_unique(); } - -OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) { - // Handle UPDATE_SIZE_UNKNOWN (0) by calculating available space - if (image_size == 0) { - // NOLINTNEXTLINE(readability-static-accessed-through-instance) - image_size = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; - } - bool ret = Update.begin(image_size, U_FLASH); - if (ret) { - esp8266::preferences_prevent_write(true); - return OTA_RESPONSE_OK; - } - - uint8_t error = Update.getError(); - if (error == UPDATE_ERROR_BOOTSTRAP) - return OTA_RESPONSE_ERROR_INVALID_BOOTSTRAPPING; - if (error == UPDATE_ERROR_NEW_FLASH_CONFIG) - return OTA_RESPONSE_ERROR_WRONG_NEW_FLASH_CONFIG; - if (error == UPDATE_ERROR_FLASH_CONFIG) - return OTA_RESPONSE_ERROR_WRONG_CURRENT_FLASH_CONFIG; - if (error == UPDATE_ERROR_SPACE) - return OTA_RESPONSE_ERROR_ESP8266_NOT_ENOUGH_SPACE; - - ESP_LOGE(TAG, "Begin error: %d", error); - - return OTA_RESPONSE_ERROR_UNKNOWN; -} - -void ArduinoESP8266OTABackend::set_update_md5(const char *md5) { - Update.setMD5(md5); - this->md5_set_ = true; -} - -OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) { - size_t written = Update.write(data, len); - if (written == len) { - return OTA_RESPONSE_OK; - } - - uint8_t error = Update.getError(); - ESP_LOGE(TAG, "Write error: %d", error); - - return OTA_RESPONSE_ERROR_WRITING_FLASH; -} - -OTAResponseTypes ArduinoESP8266OTABackend::end() { - // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5 - // This matches the behavior of the old web_server OTA implementation - bool success = Update.end(!this->md5_set_); - - // On ESP8266, Update.end() might return false even with error code 0 - // Check the actual error code to determine success - uint8_t error = Update.getError(); - - if (success || error == UPDATE_ERROR_OK) { - return OTA_RESPONSE_OK; - } - - ESP_LOGE(TAG, "End error: %d", error); - return OTA_RESPONSE_ERROR_UPDATE_END; -} - -void ArduinoESP8266OTABackend::abort() { - Update.end(); - esp8266::preferences_prevent_write(false); -} - -} // namespace ota -} // namespace esphome - -#endif -#endif diff --git a/esphome/components/ota/ota_backend_arduino_esp8266.h b/esphome/components/ota/ota_backend_arduino_esp8266.h deleted file mode 100644 index e1b9015cc7..0000000000 --- a/esphome/components/ota/ota_backend_arduino_esp8266.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#ifdef USE_ARDUINO -#ifdef USE_ESP8266 -#include "ota_backend.h" - -#include "esphome/core/defines.h" -#include "esphome/core/macros.h" - -namespace esphome { -namespace ota { - -class ArduinoESP8266OTABackend : public OTABackend { - public: - OTAResponseTypes begin(size_t image_size) override; - void set_update_md5(const char *md5) override; - OTAResponseTypes write(uint8_t *data, size_t len) override; - OTAResponseTypes end() override; - void abort() override; -#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 7, 0) - bool supports_compression() override { return true; } -#else - bool supports_compression() override { return false; } -#endif - - private: - bool md5_set_{false}; -}; - -} // namespace ota -} // namespace esphome - -#endif -#endif diff --git a/esphome/components/web_server/ota/ota_web_server.cpp b/esphome/components/web_server/ota/ota_web_server.cpp index 572c351245..b8bea40b84 100644 --- a/esphome/components/web_server/ota/ota_web_server.cpp +++ b/esphome/components/web_server/ota/ota_web_server.cpp @@ -10,9 +10,7 @@ #endif #ifdef USE_ARDUINO -#ifdef USE_ESP8266 -#include -#elif defined(USE_ESP32) || defined(USE_LIBRETINY) +#if defined(USE_ESP32) || defined(USE_LIBRETINY) #include #endif #endif // USE_ARDUINO @@ -120,9 +118,6 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Platf // Platform-specific pre-initialization #ifdef USE_ARDUINO -#ifdef USE_ESP8266 - Update.runAsync(true); -#endif #if defined(USE_ESP32) || defined(USE_LIBRETINY) if (Update.isRunning()) { Update.abort();