1. Тема дня
Архитектура безопасного OTA:
команда обновления
→ проверка условий
→ получение manifest
→ загрузка в неактивный OTA-slot
→ проверка образа
→ переключение boot partition
→ перезагрузка
→ быстрый self-test
→ подтверждение новой версии или rollbackГлавная мысль: OTA заканчивается не тогда, когда файл записан во Flash, а когда новая прошивка загрузилась, прошла самодиагностику и сохранила возможность следующего обновления.
2. Зачем это нужно
LTE-соединение EC25 может оборваться в любой момент:
- пропало покрытие;
- EC25 перерегистрировался;
- PDP context закрылся;
- оператор оборвал TCP;
- просело питание при передаче.Незаконченный образ не должен становиться загрузочным. После обновления должны продолжать работать безопасные выходы, input path, watchdog, fault manager и локальная диагностика. Потеря LTE/MQTT после перезагрузки - не всегда причина rollback: внешняя сеть может быть недоступна временно.
3. Теория
A/B OTA-разметка
Типовая структура:
bootloader
partition table
NVS
otadata
ota_0
ota_1
coredump
storageПока выполняется ota_0, новый образ пишется в ota_1. Текущая прошивка остаётся нетронутой. После проверки меняется otadata. Пример для Flash 4 MiB:
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x6000
otadata, data, ota, 0xF000, 0x2000
phy_init, data, phy, 0x11000, 0x1000
coredump, data, coredump, 0x12000, 0x10000
nvs_keys, data, nvs_keys, 0x22000, 0x1000
ota_0, app, ota_0, 0x30000, 0x1D0000
ota_1, app, ota_1, 0x200000, 0x1D0000
storage, data, fat, 0x3D0000, 0x20000Образ должен уверенно помещаться в слот, лучше оставлять 10-15% запаса.
Rollback
Включи:
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=yСостояния:
ESP_OTA_IMG_NEW
→ первая загрузка
→ ESP_OTA_IMG_PENDING_VERIFY
→ self-test
├─ успешно → ESP_OTA_IMG_VALID
└─ ошибка → ESP_OTA_IMG_INVALID → предыдущая прошивкаSelf-test после OTA
Проверяй быстро и локально:
- config load/migration/validation;
- safe outputs;
- input service;
- health supervisor;
- fault manager;
- watchdog;
- критичные задачи созданы.Не надо ждать MQTT broker или регистрацию EC25 несколько минут. Внешняя сеть может быть недоступна, а прошивка всё равно рабочая. Каркас:
static bool ota_critical_self_test(void)
{
if (!config_load_migrate_validate()) return false;
if (!safe_outputs_apply()) return false;
if (!input_service_start_and_self_test()) return false;
if (!health_supervisor_start()) return false;
if (!fault_manager_start()) return false;
if (!modem_transport_init()) {
system_enter_degraded_mode(DEGRADED_NO_MODEM);
}
return true;
}Manifest
Один URL недостаточен. Нужен manifest:
{
"schema": 1,
"project": "traffic-controller",
"version": "1.8.0",
"build_number": 184,
"chip": "esp32",
"hw_rev_min": 2,
"hw_rev_max": 4,
"image_size": 1327104,
"sha256": "8a7c...",
"url": "https://fw.example.com/controller/1.8.0/app.bin"
}Проверяй project, chip, hardware revision, размер, downgrade policy, SHA-256, TLS policy.
OTA через EC25
Вариант A - PPPoS: ESP32 поднимает PPP через UART EC25, затем использует обычный HTTPS OTA. Вариант B - EC25 HTTP AT: модем получает файл, ESP32 читает его порциями и пишет через esp_ota_write(). Здесь особенно опасны бинарные данные, URC, потеря байта, переполнение UART и повторная запись блока. MQTT лучше использовать как команду/триггер, а сам образ передавать по HTTPS.
4. Типичные ошибки
- Подтвердить firmware в начале app_main().
- Сделать MQTT обязательным self-test.
- Использовать HTTPS без проверки сертификата.
- Удалённо обновлять partition table без отдельной recovery-архитектуры.
- Не проверять аппаратную ревизию.
- Записывать progress в NVS после каждого блока.
- Включить security anti-rollback слишком рано.
5. Практическое задание
- Создай partitions_ota_4mb.csv.
- Включи rollback.
- Реализуй ota_confirm_if_pending().
- Добавь ota status.
- Сделай HIL-тест rollback: firmware B один раз запускается, self-test возвращает false, после reboot загружается A.
CLI пример:
ota status:
state=DOWNLOAD
running=ota_0
target=ota_1
current_version=1.7.4
target_version=1.8.0
written=786432
total=1327104
progress=59%
transport=EC25_PPP
last_error=OK6. Что попробовать дальше
- Power-cut tests на 10%, 50%, 99% загрузки.
- LTE разрыв во время скачивания.
- Неверный manifest/hash/project/hw_rev.
- Crash до подтверждения OTA.
- Недоступный MQTT при исправной основной функции.
Задание
Новый образ загрузился правильно, но MQTT broker недоступен. Определите решение подтверждения, отделяющее локальную исправность прошивки от внешнего сетевого отказа.
Критерии самопроверки: Перечислить локальные проверки и объяснить отдельный fault domain внешней сети. Не подтверждать образ до локального self-test.
Показать ответ автора
Локальным self-test проверить конфигурацию, safe outputs, input service, supervisor, fault manager, watchdog и критичные задачи. Не требовать внешнего MQTT для подтверждения локально исправного образа; сетевой отказ сообщать отдельно.
Задание
Спроектируйте OTA-тест потери питания, доказывающий, что неполный образ не заменяет работающую прошивку.
Критерии самопроверки: Наблюдать полноту образа и выбор загрузки. Один download progress log не доказывает безопасное восстановление.
Показать ответ автора
Прервать загрузку в неактивный слот, перезагрузить и проверить запуск предыдущей валидной прошивки. Записать target slot, written size, результат verification и boot selection; затем проверить полный образ с неуспешным локальным self-test и rollback.