Перейти к содержимому

OTA обновления прошивки “по воздуху” для ESP8266 и ESP32 на платформе Arduino

Добрый день, уважаемые читатели.

В прошлой статье, посвященной OTA обновлениям в ESP-IDF, я рассказывал, как можно реализовать механизм обновлений без использования физического подключения к микроконтроллеру ESP32 с использованием платформы ESP-IDF. Ну а в этой статье я расскажу как это же самое сделать для ESP8266 или ESP32 и платформы Arduino в Arduino IDE или PlatformIO. Если вы пока ещё не знаете, что такое платформа, ESP-IDF и т.д., то рекомендую вам начать с этой статьи.


 

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

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

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

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


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

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

  • Отправить файл с прошивкой напрямую на устройство, используя предварительно открытый специальный порт на устройстве. Вроде бы удобно, но этот способ можно использовать только в локальной сети. И возникает необходимость постоянно держать открытым порт на устройстве и мониторить его. Насколько я помню, этот способ реализован в Arduino IDE.
  • Использовать промежуточный WEB-сервер в сети интернет (по протоколу httpS) или локальный (можно использовать просто http). В этом случае файл с прошивкой предварительно загружается на этот сервер. Затем устройству отправляется прямая ссылка на загруженный файл любым удобным способом – через MQTT, telegram, web-интерфейс. Либо запускаем процесс обновления по расписанию и т.д. и т.п. В этом случае обновление можно “доставить” на целевое устройство в любую точку планеты, где есть интернет.
  • Если на вашем устройстве реализован полноценный telegram-бот (например с помощью готовой библиотеки FastBot), то можно доставлять сообщения на устройство через него. 

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

Какой WEB-сервер вам необходим?

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

? Если вам требуется легко и просто обновлять устройства, которые расположены вне вашей локальной сети (из дома обновить устройство на даче, из офиса – в соседний офис и т.д.) то рассмотрите вопрос использования любого бесплатного или платного хостинга в сети интернет, но он должен иметь поддержку защищенных TLS-соединений. 

? Если же вам необходимо обновлять ваши устройства, которые подключены к одному и тому – же роутеру (точке доступа wifi), то проще всего использовать локальные варианты WEB-сервера, как то:

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

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

В данной статье рассмотрен процесс с использованием внешнего сервера (хостинга) с использованием защищенных соединений.

 


 

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

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

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

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

Для ESP32 можно создавать произвольные таблицы разметки памяти, но для ESP8266 такой возможности нет. Можно использовать только готовые варианты разметки в виде ld-скриптов. Список доступных к использованию вариантов разметки flash-памяти вы можете найти здесь: esp8266/Arduino/tree/master/tools/sdk/ld.

Соответственно, нам требуется активировать разметку, которая будет содержать искомые два OTA-раздела. Как это сделать?

Arduino IDE

В Arduino IDE выбор разметки flash осуществляется очень просто: Инструменты -> Flash size -> выберите один из вариантов с OTA разделами, который подходят именно вам:

Выбор размера OTA-разделов в Arduino IDE

Выбор размера OTA-разделов в Arduino IDE

В зависимости от выбранного варианты размер OTA разделов будет разный, выбирайте вариант, в который “влезет” весь созданный вами код. На этом подготовку разделов памяти для Arduino IDE можно считать законченной.

VS Code + PlatformIO

В PlatformIO выбор разметки flash-памяти осуществляется, как всегда, через файл настройки проекта platformio.ini. Для этого добавьте в него следующую строку:

OTA-обновления для ESP8266 и Arduino

Как видите, это не намного сложнее чем в Arduino IDE, нужно лишь правильно выбрать нужный ld скрипт. Список доступных вариантов вы можете найти здесь: github.com/esp8266/Arduino.


 

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

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

#include <ESP8266httpUpdate.h>

Ни в Arduino IDE, ни в PlatformIO ничего дополнительно скачивать и устанавливать не требуется, это системная библиотека, включенная в framework Arduino для ESP8266.

Далее напишем функцию, которая будет принимать на вход ссылку на бинарник с новой прошивкой и запускать обновление. Она ещё проще, чем для ESP32 и ESP-IDF:

OTA-обновления для ESP8266 и Arduino

Ничего хитрого в ней нет – объявляем локальную переменную на “безопасный” wifi клиент и запускаем с помощью него обновление, передав ссылку. Если обновление пройдет успешно, микроконтроллер будет автоматически перезагружен. Впрочем, можно обойтись и без функции, но это на ваш вкус.

Предупреждение!

Для установки и поддержания защищенного соединения требуется достаточно много памяти. Поскольку TLS был разработан для систем с большим объемом памяти, им по умолчанию требуется буфер размером 16 КБ для приема и передачи. А всего на одно TLS-соединение библиотекой BearSSL может расходоваться до 22 КБ оперативной памяти (пруфы здесь). Поэтому для ESP8266, у которого общая доступная куча составляет всего около 40 КБ, одновременно возможно использовать только одно защищенное соединение.

Подробнее об защищенных соединениях на ESP8266 вы можете почитать тут. Если у вас уже “занято” защищенное соединение в другом месте прошивки – вам придется использовать открытое соединение WiFiClient, но на свой страх и риск. Либо отказаться от защищенного соединения в этом другом месте. Либо переходить на ESP32, где гораздо больше оперативной памяти, но там немного другие библиотеки и классы.

 


Где взять двоичный файл с прошивкой

Где взять двоичный файл с прошивкой, который будет отправлять на устройство?

Для ArduinoIDE существует специальная команда “Экспорт бинарного файла”, которая как раз и предназначена для получения двоичного файла прошивки:

OTA-обновления для ESP8266 и Arduino

Файл после этого вы найдете прямо в каталоге с вашим скетчем.

 

Для PlatformIO необходимо скомпилировать проект командой build, а затем найти файл %prj_dir%\.pio\build\%prj_obj%\firmware.bin, где:

  • firmware.bin – это и есть тот самый файл с прошивкой
  • %prj_dir% – каталог проекта, то есть тот каталог, в котором расположен файл platfromio.ini
  • %prj_obj% – название секции устройства в platfromio.ini, для которого производится компиляция, например nodemcuv2

Затем двоичный файл нужно любым способом загрузить на доступный вам HTTPS-ресурс и получить прямую ссылку на него. Это зависит от используемого сервера, поэтому здесь не может быть общих рекомендаций.


 

Отправляем уведомление на устройство о том, что нужно обновиться

Теперь нужно любым удобным способом оповестить устройство о том, что нужно скачать новую прошивку. Сделать это можно следующими способами:

  • Можно обновлять прошивку из одного и того же сервера и каталога один раз в сутки или в неделю и т.д. В этом случае вы заранее прошиваете в устройство путь к файлу прошивки и расписание обновления, а потом устройство самостоятельно обновляется без вашего участия.
  • Отправить ссылку на файл через MQTT сервер в заранее определенный топик, например device/ota. Получив сообщение в этом топике, устройство понимает, что нужно обновить прошивку немедленно. Я предпочитаю именно этот способ.
  • Создать web-интерфейс на вашем устройстве и добавить поле для ввода ссылки на новую прошивку и кнопку для запуска обновления.
  • Отправить ссылку на файл через telegram-бота или любой другой канал связи (mail например).

Как я уже написал, я предпочитаю использовать проверенный способ – через MQTT, чем и займемся далее. Я использую скетч, написанный для одной из предыдущих статей, и просто добавлю в него функции ОТА-обновления.

Телеметрия на Arduino и ESP8266. Создание проекта с MQTT управлением в среде PlatformIO

Возьмём скетч, написанный для предыдущей статьи, и доработаем его:

  • Во первых добавим функцию, что я привёл выше.
  • Во вторых объявим необходимые константы:

OTA-обновления для ESP8266 и Arduino

  • Затем добавим код подписки на этот топик сразу после подключения к брокеру:

OTA-обновления для ESP8266 и Arduino

  • Ну и добавим чуть-чуть кода в функцию обработки входящих сообщений с сервера:

OTA-обновления для ESP8266 и Arduino

Вот, собственно и все доработки проекта. Все готово.

В первый раз придется залить все эти доработки в микроконтроллер по кабелю.


Как всем этим пользоваться?

1. Скомпилировать проект и получить двоичный (бинарный) файл с кодом прошивки, как описано выше.

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

3. После загрузки файла на сервер получить https-ссылку на него и отправить её в топик device/ota, например с использованием MQTT Explorer или любым другим удобный способом.

4. Дождаться перезагрузки устройства. Enjoy!

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


Перед обновлением отключите реле, управляющее нагрузкой

ОТА – обновление – штука медленная. И иногда не предсказуемая. Устройство может зависнуть или начать спонтанно перезагружаться. Не часто, но такое вполне возможно. Как правило это происходит либо из-за проблем в прошивке, которые вы же сами и допустили; либо из-за очень медленного и загруженного канала связи.

Поэтому после того, как вы получили ссылку на файл обновления – приостановите все критичные процессы. Отключите нагрузку, которой управляет устройство. В общем, примите все необходимые меры, дабы предотвратить неожиданные и аварийные ситуации в случае зависания устройства, например.


 

Ссылки

Пример проекта с использованием ОТА-механизма вы можете найти здесь: arduino/arduino_eps8266_ota

Благодарю за внимание!

? Архив статей, упорядоченный по категориям ?


Пожалуйста, оцените статью:
[ 3 из 5, всего 2 оценок ]

6 комментариев для “OTA обновления прошивки “по воздуху” для ESP8266 и ESP32 на платформе Arduino”

    1. Работает. Я этим кодом много времени пользовался, пока esp8266 использовал. И всегда успешно.
      Так что если у вас не работает – значит что-то делаете не так.

      1. Ну реально не работает стоит лишь указать вместо http защищенный https
        CALLBACK: HTTP update fatal error code -1
        Cloud update: Update failed! Error (-1): HTTP error: connection failed

        а если указать http и WiFiClient otaWiFi; вместо WiFiClientSecure otaWiFi;
        то отлично отрабатывает. но не люблю открывать http

        1. И правильно!
          В случае с ESP8266 следует всегда помнить, два httpS соединения одновременно она не тянет. По определению. Поэтому если вы где-то уже использовали TLS в своей прошивке, второе соединение работать не будет. А вот если их больше нет – прекрасно работает.

          Когда у меня еще были устройства на ESP8266, они подключались к локальному брокеру внутри локалки без TLS, поэтому способ из статьи прекрасно работал. Он вполне себе проверен. И не раз и не два, а много раз.

          Кроме того, раньше, в старых версиях фреймворка Arduino для ESP8266, была другая библиотека TLS, она не проверяла сертификаты, зато экономила кучу памяти. И тоже все работало. Но ее за это “небезопасное поведение” все ругали – вот её разработчики и заменили. Получите и распишитесь.

          Хотите больше – переходите на ESP32, но там немного другие библиотеки. Это тоже следует учитывать.

          Но вы правы в том, что об этом ничего не сказано было в статье. Добавил. И добавил ссылочку на статью про TLS на ESP8266.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *