diff --git a/esphome/components/ota/__init__.py b/esphome/components/ota/__init__.py index 8f31eb5cdd..579491fe1a 100644 --- a/esphome/components/ota/__init__.py +++ b/esphome/components/ota/__init__.py @@ -24,6 +24,8 @@ def AUTO_LOAD() -> list[str]: components = ["safe_mode"] if not CORE.using_zephyr: components.extend(["md5"]) + if CORE.is_esp32: + components.extend(["watchdog"]) return components diff --git a/esphome/components/ota/ota_backend_esp_idf.cpp b/esphome/components/ota/ota_backend_esp_idf.cpp index f5b8f14cfe..7200eb752e 100644 --- a/esphome/components/ota/ota_backend_esp_idf.cpp +++ b/esphome/components/ota/ota_backend_esp_idf.cpp @@ -10,6 +10,7 @@ #include #ifdef USE_OTA_PARTITIONS +#include "esphome/components/watchdog/watchdog.h" #include #include #endif @@ -222,6 +223,18 @@ OTAResponseTypes IDFOTABackend::update_partition_table() { ESP_LOGE(TAG, "esp_partition_table_verify failed (new partition table) (err=0x%X) ", err); return OTA_RESPONSE_ERROR_PARTITION_TABLE_VERIFY; } + // Check for missing checksum + // esp_partition_table_verify does not fail in this case and the ESP would not boot after the update + bool checksum_found = false; + for (size_t i = 0; i < ESP_PARTITION_TABLE_MAX_ENTRIES; i++) { + if (((const esp_partition_info_t *)&new_partition_table[i])->magic == ESP_PARTITION_MAGIC_MD5) { + checksum_found = true; + } + } + if (!checksum_found) { + ESP_LOGE(TAG, "New partition table has no checksum", err); + return OTA_RESPONSE_ERROR_PARTITION_TABLE_VERIFY; + } // Check if the required app and otadata partitions exist in the new partition table // Check which app slot to boot from in the new partition table @@ -284,7 +297,6 @@ OTAResponseTypes IDFOTABackend::update_partition_table() { esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, NULL); while (it != NULL) { const esp_partition_t *p = esp_partition_get(it); - const esp_partition_info_t *new_part = &new_partition_table[app_index == -1 ? app_index_with_copy : app_index]; if (p->address == running_app_offset && p->size >= running_app_size) { running_app_part = p; } @@ -294,29 +306,9 @@ OTAResponseTypes IDFOTABackend::update_partition_table() { ESP_LOGD(TAG, "Copying running app from 0x%X to 0x%X (size: 0x%X)", running_app_part->address, app_copy_target_part->address, running_app_size); -#if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15 - // The following function takes longer than the 5 seconds timeout of WDT - esp_task_wdt_config_t wdtc; - wdtc.idle_core_mask = 0; -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 - wdtc.idle_core_mask |= (1 << 0); -#endif -#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 - wdtc.idle_core_mask |= (1 << 1); -#endif - wdtc.timeout_ms = 15000; - wdtc.trigger_panic = false; - esp_task_wdt_reconfigure(&wdtc); -#endif - + watchdog::WatchdogManager watchdog(15000); err = esp_partition_copy(app_copy_target_part, 0, running_app_part, 0, running_app_size); -#if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15 - // Set the WDT back to the configured timeout - wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000; - esp_task_wdt_reconfigure(&wdtc); -#endif - if (err != ESP_OK) { ESP_LOGE(TAG, "esp_partition_copy failed (err=0x%X) ", err); return OTA_RESPONSE_ERROR_PARTITION_TABLE_UPDATE;