Esp32 firmware by wifi

Механизм OTA обновлений прошивки «по воздуху» для ESP32 и ESP-IDF

Добрый день, уважаемые читатели! В этой статье я расскажу, как достаточно просто и легко выполняются OTA-обновления на микроконтроллере ESP32 и фреймворке ESP-IDF.

Совсем не сложно провернуть то же самое и на ESP8266 и Arduino. И я, быть может, даже расскажу об этом в следующей статье. Но в данном тексте речь пойдет только об ESP32 и ESP-IDF.

Что такое ОТА?

OTA — это обновление устройств, которое устанавливается при помощи Wi-Fi соединения или мобильного интернета (в случае со смартфонами). Аббревиатура OTA произошла от английского «Over the Air», а еще раньше это называлось «Firmware Over The Air» — что в переводе с английского означает «микропрограмма по воздуху».

Согласитесь, что намного удобнее обновлять «прошивки» умных устройств удаленно, без необходимости физического подключения кабелем к плате микроконтроллера. Особенно если это устройство установлено где-то глубоко в недрах кухонной вытяжки или, например, на чердаке. А особенно удобно обновлять (и добавлять новые функции, кстати) устройства, которые вообще находятся «за тридевять земель» и возможности физического подключения к ним нет вообще.

В общем с какой стороны не глянь — одни плюсы. Но на самом деле это не так, минусы то же имеются. Обо всем этом и поговорим в данной статье.

Способы доставки ОТА-обновлений

Чтобы использовать технологию ОТА-обновлений, необходимо как минимум скомпилировать исходники и «доставить» полученный двоичный файл с прошивкой непосредственно на устройство. Я знаю как минимум два способа доставки бинарного файла на устройства:

  • Отправить файл с прошивкой напрямую на устройство, используя предварительно открытый специальный порт на устройстве. Вроде бы удобно, но этот способ можно использовать только в локальной сети. И возникает необходимость постоянно держать открытым порт на устройстве и мониторить его. Насколько я помню, этот способ реализован в Arduino IDE.
  • Использовать промежуточный сервер в сети интернет. В этом случае файл с прошивкой предварительно загружается на этот сервер (например хостинг). Затем устройству отправляется прямая ссылка на загруженный файл любым удобным способом — через MQTT, telegram, web-интерфейс. Либо запускаем процесс обновления по расписанию и т.д. и т.п. В этом случае обновление можно «доставить» на целевое устройство в любую точку планеты, где есть интернет.

Следует учитывать, что файл с прошивкой должен быть размещен на таком ресурсе, где он доступен для скачивания по прямой ссылке. Яндекс Диск, Google Disk, Dropbox для этих целей не подойдут, так как ссылка на файл в этом случае ведёт не на сам файл, а на промежуточную страницу!

Есть и ещё способы отправить прошивку на устройство с использованием сторонних сервисов, но я ими не пользовался.

Я использую второй способ (с использованием промежуточного сервера), используя в качестве него виртуальный хостинг, на котором расположен мой сайт. И именно про этот способ пойдет речь в этой статье.

Подготовка разметки flash-памяти

Прежде чем начинать эксперименты с OTA-обновлениями, необходимо соответствующим образом подготовить разметку flash-памяти устройства.

Для OTA-обновлений потребуется как минимум два отдельных раздела с типом app / ota_x под хранение данных прошивок:

  • С одного раздела запускается устройство в текущий момент, этот раздел называется активным .
  • В другой раздел ( неактивный ) может записываться новая прошивка при получении её через OTA без риска нарушения работоспособности текущей прошивки.
Читайте также:  Снести драйвера вай фай

Размеры этих разделов должны быть не менее, чем это требуется для загрузки всей микропрограммы, которую вы создали. Можно создать и больше ota разделов — например три или пять, максимум 16. Но лично я не вижу в этом особого смысла, всё равно работать будет только одна.

Кроме того, обязательно потребуется создать ещё один раздел otadata с типом data / ota , в котором загрузчик хранит служебные данные об активном разделе. После того, как данные новой прошивки были успешно получены и записаны в неактивный раздел, загрузчик помечает активным только что обновленный раздел и после программного перезапуска пробует загрузиться уже с новой прошивкой.

Если вдруг «что-то пошло не так», и новая прошивка не работает как требуется, ESP-IDF предоставляет возможность автоматически откатится на предыдущую версию путем отката активного раздела на предыдущий. Более подробно об этом будет рассказано ниже.

Дополнительно (если позволяет размер вашей прошивки и свободное место на flash-памяти) можно создать раздел factory с типом app / factory , в котором содержится «заводская» прошивка. Этот раздел будет использован, если служебный раздел otadata чист и не содержит никаких сведений об активной прошивке. Но это не обязательно — если они отсутствует, то будет использован раздел ota_0 .

Пример переключения между разделами ОТА: 1 — состояние после прошивки «кабелем» 2 — состояние после первого OTA обновления 3 — состояние после второго ОТА-обновления 4 — состояние после третьего ОТА-обновления или если второе завершилось не удачно

В рамках данной статьи я не буду касаться тонкостей создания файла разметки разделов, этому нужно посвятить отдельную статью. Для целей проверки OTA вполне достаточно использовать стандартную разметку » Factory app, two OTA definitions «, которая выглядит следующим образом:

Эта разметка подходит для модулей с доступной flash памятью 4МБ (самых распространенных). Как видите, здесь выделено по 1МБ выделено под два OTA-раздела, еще 1МБ под заводскую прошивку, и остальные 1МБ распределены под загрузчик, otadata, nvs и данные физической инициализации. На мой взгляд, это далеко не оптимальная разметка, но для тестовых целей вполне сгодится.

Итак, подготавливаем разделы

Заходим в sdkconfig , находим раздел (Top) → Partition Table → Partition Table и выбираем пункт » Factory app, two OTA definitions «:

Не забываем сохранить конфигурацию перед выходом.

После этого компилируем проект (хотя-бы пустой) и загружаем его в устройство через USB или COM — порт . Загрузчик и таблица разделов записываются только при «физической» прошивке.

«Потом» через ОТА изменить таблицу разделов не получится, равно как и изменить параметры отката неудачной прошивки, так как за все это отвечает именно загрузчик. Поэтому выполняем этот этап максимально тщательно, особенно если физического доступа к устройству после установки на постоянного место работы не планируется.

После того, как новая таблица разделов и настроенный загрузчик записаны на flash, уже таки можно приступать к программированию OTA.

Код загрузки новой прошивки через HTTPS

Как ни страшно звучит OTA с первого взгляда, код для загрузки новой прошивки по заданному URL выглядит достаточно просто:

1. Первым шагом настраиваем самое обычное HTTPS-подключение , но обязательно с TLS-шифрованием (без HTTPS прошивка загружаться отказывается). Через поле cfgHTTPS.url = otaSource ; передаем прямую ссылку на двоичный файл с новой версией прошивки .

Приведенный на скриншоте код позволяет в зависимости от настроек в файле конфигурации выбрать либо сертификат в буфере, либо пакет, либо централизованное хранилище.

Читайте также:  Изменить пароль wifi казахтелеком

Источник

Прошивка esp32 — по воздуху, через wi-fi

Каждый, кто хоть раз занимался хобби-проектами на основе микроконтроллеров, знает, что такая идея проходит множество итераций, прежде чем займёт своё законное место на пыльной полке будет служить верой и правдой.

Обновление программного обеспечения при этом довольно часто становится одной из основных задач. В этой статье мы попробуем испытать способ, который позволит любому разработчику обновлять своё программное обеспечение легко и просто — прямо через сеть wi-fi! При этом задача существенно облегчится, если мы возьмём для экспериментов замечательный микроконтроллер esp32, так как он уже имеет в своём составе wifi-адаптер.

Обновление по воздуху (англ. over-the-air, OTA) предполагает разные методы распространения новых версий программ, настроек и обновлений ключей шифрования для телефонов, ресиверов и устройств зашифрованной передачи речи (двухканальные рации с шифрованием).

Что же касается esp32, то обновление по воздуху является весьма интересной «фишкой», так как позволяет обновлять программу на устройствах, доступ к которым осложнён или невозможен. Например, если устройство расположено где-то высоко (на дереве или фонарном столбе).

Интересным моментом такого рода обновлений является возможность постоянно апдейтить приложения на целой сети устройств, используя для этого центральный сервер с программным обеспечением.

Давайте попробуем реализовать нечто подобное.

Заранее хочу оговориться, что все необходимые файлы находятся внизу под статьёй, и вы можете скачать их по предложенным ссылкам. Все материалы полностью рабочие и протестированы лично.

Сначала нам необходимо зайти на официальный сайт и скачать python версии 2.7.15. Возможно, будет работать и с другой версией, но я пробовал только с этой. Я скачивал 64-битную версию под windows 7 (вот такой я ретроград! 🙂 ).

Далее вам необходимо установить её на компьютер для всех пользователей:

На следующем шаге необходимо выбрать опцию, как я показал на рисунке ниже:

Проблема в том, что изначально плата esp32 совсем не обладает функционалом для обновления программ по воздуху, поэтому нам необходимо выбрать из примеров опцию ArduinoOTA, как показано ниже:

Далее в предложенный ниже код мы должны вставить название своей точки доступа, к которой мы будем подключаться, а также её пароль. После чего прошьём этим скетчем свою плату:

#include #include #include #include const char* ssid = "testNet"; const char* password = "parole"; void setup() < Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) < Serial.println("Connection Failed! Rebooting. "); delay(5000); ESP.restart(); >ArduinoOTA .onStart([]() < String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); >) .onEnd([]() < Serial.println("\nEnd"); >) .onProgress([](unsigned int progress, unsigned int total) < Serial.printf("Progress: %u%%\r", (progress / (total / 100))); >) .onError([](ota_error_t error) < Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); >); ArduinoOTA.begin(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); > void loop()

Дальше вам будет необходимо запустить монитор порта, предварительно выбрав сам порт, к которому подключена плата и который мы будем мониторить.

Если кто не знает, делается это так, как показано на картинке ниже, то есть можно выбрать среди доступных COM-портов тот самый, к которому у вас подключена esp32. Скорее всего, у вас там будет отображаться несколько портов, один из которых — ваш нужный. Ничего страшного, если вы немного «потыкаетесь» и найдёте методом тыка нужный порт. Однако, если вы хотите поступить более правильным образом, следует нажать на значок компьютера на рабочем столе (повторяю, у меня – Win’7) правой кнопкой мыши и пройти по пути, как показано ниже. Таким образом вы сможете выяснить порт, к которому подключена у вас esp32, это нужно, чтобы вы знали, какой порт необходимо мониторить.

Читайте также:  Wi fi bec wfn 02

Если в мониторе порта ничего не показывается — то вам необходимо нажать на кнопку «EN» на плате esp32, что приведёт к перезагрузке платы, и в монитор порта выведется вся необходимая информация.

Если всё прошло успешно, то в конце этой информации будет показан IP-адрес, который был выдан вашей плате точкой доступа wi-fi, к которой плата подключилась:

Теперь мы внесём изменения в этот скетч, чтобы при его повторной загрузке в плату, что-то происходило. Например, сделаем так, чтобы встроенный в плату светодиод мерцал с некоторым интервалом.

Для этого в приведённый выше код были внесены некоторые изменения, которые показаны на рисунке ниже:

Сам изменённый код будет выглядеть следующим образом:

#include #include #include #include const char* ssid = "testNet"; const char* password = "parole"; //переменные для мигания светодиодом через millis const int led = 2; unsigned long previousMillis = 0; const long interval = 1000; int ledState = LOW; void setup() < pinMode(led, OUTPUT); Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) < Serial.println("Connection Failed! Rebooting. "); delay(5000); ESP.restart(); >ArduinoOTA .onStart([]() < String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); >) .onEnd([]() < Serial.println("\nEnd"); >) .onProgress([](unsigned int progress, unsigned int total) < Serial.printf("Progress: %u%%\r", (progress / (total / 100))); >) .onError([](ota_error_t error) < Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); >); ArduinoOTA.begin(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); > void loop() < ArduinoOTA.handle(); unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) < previousMillis = currentMillis; ledState = not(ledState); digitalWrite(led, ledState); >> 

Загрузим этот код в нашу плату. И тут возникает один очень интересный момент: у вас в списке COM-портов появляется сетевой порт, имеющий IP адрес — это и есть наша плата esp32!

Выберем её и нажмём на загрузку скетча. В результате в нижнем окошке появится следующий статус происходящего: будет увеличиваться в длину индикатор загрузки и расти процент:

Кстати сказать, во время этой загрузки у меня плата была подключена к power-банку, т.е. была отключена от компьютера, и загрузка производилась непосредственно через сеть wi-fi.

В качестве небольшого примечания следует сказать, что код, поддерживающий беспроводную загрузку (первый кусок кода в этой статье), должен быть всегда включён в ваш скетч (который выполняет какую-либо полезную деятельность для вас). Если этого не сделать, то вы потеряете возможность загружать скетчи «по воздуху».

P.S. Если кого-то интересует прошивка по воздуху предыдущей версии платы (esp8266), то вот тут есть весьма подробный мануал.

Загрузки:

НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS .

Источник

Оцените статью
Adblock
detector