ESP8266:Прошивки/Arduino/OTA-апдейты: различия между версиями

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
 
Нет описания правки
 
(не показаны 2 промежуточные версии 2 участников)
Строка 3: Строка 3:
{{Myagkij-редактор}}
{{Myagkij-редактор}}


{{Черновик}}
 


=OTA-апдейты<ref>[http://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html arduino-esp8266.readthedocs.io - OTA Updates]</ref>=
=OTA-апдейты<ref>[http://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html arduino-esp8266.readthedocs.io - OTA Updates]</ref>=
Строка 26: Строка 26:
Улучшить защиту [[OTA-апдейт]]а можно при помощи библиотеки ArduinoOTA:
Улучшить защиту [[OTA-апдейт]]а можно при помощи библиотеки ArduinoOTA:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
void setPort(uint16_t port);
void setPort(uint16_t port);
void setHostname(const char* hostname);
void setHostname(const char* hostname);
Строка 44: Строка 44:
Функции ниже служат для управления вашим проектом во время некоторых стадий [[OTA-апдейт]]а или при ошибке, возникшей во время [[OTA-апдейт]]а:
Функции ниже служат для управления вашим проектом во время некоторых стадий [[OTA-апдейт]]а или при ошибке, возникшей во время [[OTA-апдейт]]а:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
void onStart(OTA_CALLBACK(fn));
void onStart(OTA_CALLBACK(fn));
void onEnd(OTA_CALLBACK(fn));
void onEnd(OTA_CALLBACK(fn));
Строка 58: Строка 58:
Эту функцию можно использовать, чтобы узнать размер свободного места для нового скетча:
Эту функцию можно использовать, чтобы узнать размер свободного места для нового скетча:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
ESP.getFreeSketchSpace();
ESP.getFreeSketchSpace();
</syntaxhighlight>
</syntaxhighlight>
Строка 135: Строка 135:
В защите [[OTA-апдейт]]а паролем нет ничего сложного. Все, что нужно – это прописать в [[скетч]]е следующую функцию:
В защите [[OTA-апдейт]]а паролем нет ничего сложного. Все, что нужно – это прописать в [[скетч]]е следующую функцию:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.setPassword((const char *)"123");
</syntaxhighlight>
</syntaxhighlight>
Строка 214: Строка 214:
==== Блок setup() ====
==== Блок setup() ====


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
MDNS.begin(host);
MDNS.begin(host);


Строка 225: Строка 225:
==== Блок loop() ====
==== Блок loop() ====


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
httpServer.handleClient();
httpServer.handleClient();
</syntaxhighlight>
</syntaxhighlight>
Строка 300: Строка 300:
Простой апдейтер загружает файл с каждым вызовом апдейтной функции:
Простой апдейтер загружает файл с каждым вызовом апдейтной функции:


<syntaxhighlight lang="c" enclose="div">
<syntaxhighlight lang="c">
ESPhttpUpdate.update("192.168.0.2", 80, "/arduino.bin");
ESPhttpUpdate.update("192.168.0.2", 80, "/arduino.bin");
</syntaxhighlight>
</syntaxhighlight>
Строка 310: Строка 310:
Серверный скрипт может ответить по-разному. Во-первых, он может прислать код '''«200»''' и выслать образ прошивки, а во-вторых, ответить кодом '''«304»''', и это будет значить, что [[ESP8266]] обновление не требуется.
Серверный скрипт может ответить по-разному. Во-первых, он может прислать код '''«200»''' и выслать образ прошивки, а во-вторых, ответить кодом '''«304»''', и это будет значить, что [[ESP8266]] обновление не требуется.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
t_httpUpdate_return ret = ESPhttpUpdate.update("192.168.0.2", 80, "/esp/update/arduino.php", "здесь опциональный аргумент с версией");
t_httpUpdate_return ret = ESPhttpUpdate.update("192.168.0.2", 80, "/esp/update/arduino.php", "здесь опциональный аргумент с версией");
switch(ret) {
switch(ret) {
Строка 339: Строка 339:
Вот пример данных, присылаемых от [[ESP8266]]:
Вот пример данных, присылаемых от [[ESP8266]]:


<syntaxhighlight lang="bash" enclose="div">
<syntaxhighlight lang="bash">
[HTTP_USER_AGENT] => ESP8266-http-Update
[HTTP_USER_AGENT] => ESP8266-http-Update
[HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA
Строка 355: Строка 355:
Пример скрипта:
Пример скрипта:


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
<?PHP
<?PHP


Строка 444: Строка 444:


=См.также=
=См.также=


=Внешние ссылки=
=Внешние ссылки=


<references />
<references />
{{Навигационная таблица/Портал/ESP8266}}


[[Категория:ESP8266]]
[[Категория:ESP8266]]

Текущая версия от 12:51, 18 июня 2023

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.



OTA-апдейты[1]

OTA-апдейт (от «over the air», т.е. «по воздуху») – это процесс загрузки прошивки на ESP8266 не через последовательный порт, а по WiFi. Данный способ очень удобен, если ESP8266 установлен таким образом, что до него трудно или даже невозможно добраться.

OTA-апдейт можно выполнить при помощи:

  1. IDE Arduino
  2. Браузера
  3. HTTP-сервера

OTA-апдейт при помощи IDE Arduino используется, как правило, на стадии разработки ПО. После разработки лучше использовать браузер (для ручного обновления) или HTTP-сервер (для автоматического обновления).

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

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

Защита от взломов

Чтобы на ESP8266 можно было загрузить новую прошивку, он должен быть открыт другим участникам беспроводной сети. Но это несет риск того, что ESP8266 могут взломать и загрузить на него новый код. Чтобы снизить вероятность взлома, апдейт можно защитить при помощи пароля, специального OTA-порта и т.д.

Улучшить защиту OTA-апдейта можно при помощи библиотеки ArduinoOTA:

void setPort(uint16_t port);
void setHostname(const char* hostname);
void setPassword(const char* password);

Некоторые защитные средства встроены в ArduinoOTA по умолчанию и не требуют дополнительного кода. В библиотеке ArduinoOTA и скрипте «espota.py» используется дайджест-аутентификация апдейта. Целостность передаваемых данных проверяется со стороны ESP8266 при помощи контрольной суммы MD5.

Проанализируйте свой проект, чтобы понять, какие именно функции ArduinoOTA для него потребуются. Если нужно, примените и другие защитные меры. Например, показ ESP8266 другим участникам сети по специальному графику, запуск OTA-апдейта только при нажатии на специальную кнопку, подключенную к ESP8266, и т.д.

Стабильная работа проекта

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

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

Функции ниже служат для управления вашим проектом во время некоторых стадий OTA-апдейта или при ошибке, возникшей во время OTA-апдейта:

void onStart(OTA_CALLBACK(fn));
void onEnd(OTA_CALLBACK(fn));
void onProgress(OTA_CALLBACK_PROGRESS(fn));
void onError(OTA_CALLBACK_ERROR (fn));

Базовые требования

Размер flash-памяти должен быть таким, чтобы одновременно вмещать и старый (тот, что загружен на ESP8266 в данный момент), и новый (загружаемый через OTA) скетчи. Также имейте в виду, что в файловой системе и EEPROM тоже должно быть достаточно места (на один раз). Подробнее смотрите в этой статье, в разделе «Разбивка flash-памяти».

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

ESP.getFreeSketchSpace();

О разбивке памяти, о том, куда сохраняется новый скетч и как он копируется во время OTA-апдейта, читайте в самом последнем разделе этой статьи под названием «Разбивка памяти во время OTA-апдейта».

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

OTA-апдейт через IDE Arduino

OTA-апдейт ESP8266 при помощи IDE Arduino выполняется, как правило, в следующих случаях:

  • Во время разработки ПО (в качестве быстрой альтернативы апдейту через последовательный порт)
  • Для обновления небольшого количества ESP8266
  • Если ESP8266 находится в той же сети, что и компьютер, на котором стоит IDE Arduino

Требования

  • ESP8266 и компьютер должны находиться в одной и той же сети

Выполнение OTA-апдейта

Ниже рассказывается, как настроить OTA-апдейт на плате NodeMCU 1.0 (с модулем ESP-12E). Вы, впрочем, можете использовать любую другую плату, которая соответствует требованиям, описанным выше. Данная инструкция подходит для всех ОС, поддерживающих IDE Arduino. Скриншоты были сделаны на Windows, поэтому пользователи Linux и MacOS могут заметить небольшие отличия (вроде названия последовательного порта).

Убедитесь, что у вас установлено следующее ПО

  • IDE Arduino версии 1.6.7 или новее (скачать можно тут).
  • Аддон ESP8266 для IDE Arduino версии 2.0.0 или новее (инструкцию по установке читайте тут).
  • Python 2.7 (скачать можно тут).

Примечание: При установке Python пользователи Windows должны выбрать пункт «Add python.exe to Path» (см. ниже – эта опция по умолчанию не выбрана).

Подготовьте скетч и настройте IDE Arduino на загрузку этого скетча через последовательный порт.

  • Запустите IDE Arduino и загрузите в рабочую область скетч «BasicOTA.ino», который можно открыть, кликнув на Файл > Примеры > ArduinoOTA > BasicOTA (File > Examples > ArduinoOTA > BasicOTA).
  • Укажите в скетче собственные SSID и пароль, чтобы модуль мог подключиться к вашей WiFi-сети.
  • Настройте параметры загрузки, как показано ниже (если вы используете другую плату, то могут понадобиться другие настройки).

Примечание: В зависимости от версии платы и аддона в меню выше может быть пункт «Upload Using:». Эта опция неактивна, поэтому неважно, что именно вы в ней выберите. Ее оставили для совместимости со старыми версиями OTA и удалили лишь в версии 2.2.0.

Загрузите скетч (Ctrl+U). Загрузив, откройте монитор порта (Ctrl+Shift+M) и проверьте, подключился ли ESP8266 к WiFi-сети.

Примечание: После загрузки скетча через последовательный порт нужно выполнить сброс ESP8266. В противном случае все последующие шаги работать не будут. Сброс может быть выполнен автоматически после открытия монитора порта (как показано на скриншоте выше), и это зависит от того, подключены ли линии DTR и RST между конвертером USB-Serial и ESP8266. Если сброс не выполняется автоматически, его нужно сделать вручную либо просто выключить/включить ESP8266. Более подробно об этом читайте в [ссылка статье FAQ], в ответе на вопрос «Я наткнулся на случай, когда ESP.restart() не работает. В чем причина?»

Спустя пару секунд в IDE Arduino появится порт «esp8266-ota» (но только в том случае, если ESP8266 подключен к сети). Выберите порт с IP-адресом, который был показан ранее в мониторе порта.

Примечание: Если OTA-порт не появился, закройте IDE Arduino, потом снова откройте и проверьте, появился ли порт. Если нет, проверьте настройки фаервола и роутера. OTA-порт объявляется при помощи сервиса mDNS. Чтобы проверить, видит ли ПК этот порт, можно воспользоваться программой вроде Bonjour Browser.

Теперь приготовьтесь к самому первому OTA-апдейту – выберите OTA-порт.

Примечание: При выполнении OTA-апдейта неважно, какое значение будет стоять в пункте «Upload Speed:» (но это важно при загрузке через последовательный порт). Оставьте его без изменений.

Если вы успешно выполнили все шаги выше, можете смело выполнять OTA-апдейт (Ctrl+U) модуля ESP8266 выбранным скетчем.

Примечание: Чтобы загружать скетч при помощи OTA снова и снова, внутри него нужно прописать соответствующие функции. Для примера используйте скетч «BasicOTA.ino».

Защита паролем

В защите OTA-апдейта паролем нет ничего сложного. Все, что нужно – это прописать в скетче следующую функцию:

ArduinoOTA.setPassword((const char *)"123");

Здесь «123» – это шаблон пароля, который нужно заменить на собственный.

Перед тем, как использовать эту функцию в своем скетче, посмотрите, как она работает в скетче-примере «BasicOTA.ino», который можно открыть, кликнув в IDE Arduino на Файл > Примеры > ArduinoOTA > BasicOTA (File > Examples > ArduinoOTA > BasicOTA). Откройте «BasicOTA.ino», уберите знаки комментария у строчки, показанной выше, и загрузите скетч. Чтобы упростить задачу, не редактируйте скетч, за исключением пароля «123». Затем снова попробуйте загрузить скетч при помощи OTA-апдейта. Когда завершится компиляция и скетч начнет загружаться на ESP8266, в IDE Arduino выскочит примерно такое окно с запросом на введение пароля:

Введите пароль, и загрузка скетча продолжится как обычно, но с одним отличием – в логах загрузки появится новое сообщение «Authentication…OK».

IDE Arduino запомнит этот пароль и в следующий раз не попросит его ввести. Но вы увидите запрос на введение пароля, если перезапустите IDE Arduino или поменяете его в скетче, загрузите его, а потом попытаетесь загрузить снова.

Существует способ, позволяющий показать пароль, ранее введенный в IDE Arduino, если IDE Arduino не была закрыта после последней загрузки. Это можно сделать, кликнув в IDE Arduino на Файл > Настройки (File > Preferences) и поставив галочку рядом с пунктом «Показать подробный вывод: Загрузка» («Show verbose output during: Upload»), а затем загрузив скетч на ESP8266 еще раз.

На картинке выше видны логи, а в них – и сам пароль, передаваемый загрузочному скрипту «espota.py».

Ниже – пример ситуации, когда между загрузками пароль был изменен:

Как видите, при загрузке скетча IDE Arduino сначала пробует ввести старый пароль, но он не срабатывает. В логах об этом сообщается строчкой «Authentication…FAIL». После этого IDE Arduino запрашивает у вас новый пароль, который оказывается правильным. В результате вторая загрузка скетча проходит успешно.

Возможные проблемы

Если OTA-апдейт не удался, первым делом стоит взглянуть на сообщения об ошибках, показываемые в окне загрузки IDE Arduino. Если в них нет полезной информации, сделайте еще один OTA-апдейт, но на этот раз глядя на информацию, идущую через последовательный порт ESP8266. Монитор порта IDE Arduino в данном случае будет бесполезен. При попытке открыть его, скорее всего, откроется вот такое окно:

Это окно для Arduino Yun, в аддоне esp8266/Arduino оно пока не реализовано. Оно открывается, потому что IDE Arduino пытается открыть монитор порта при помощи сетевого порта, который вы выбрали для загрузки OTA-апдейта.

Вместо этого вам нужно открыть внешний монитор порта. Если у вас Windows, можно воспользоваться программой Termite. Это удобный и простой RS232-терминал, который не использует для управления потоком линии RTS и DTR. Такое управление потоком может вызвать проблемы, если с помощью этих линий происходит переключение контактов GPIO0 и RESET, используемых для загрузки скетча на Arduino.

Откройте внешний терминал (к примеру, тот же Termite) и, как в IDE Arduino, выставьте в нем нужные COM-порт и скорость передачи данных. Стандартные настройки Termite показаны ниже:

Затем запустите в IDE Arduino OTA-апдейт и посмотрите, что показывает терминал. При успешном выполнении OTA-апдейта при помощи скетча «BasicOTA.ino» в нем будет показано примерно следующее (IP-адрес зависит от настроек сети):

Если OTA-апдейт пройдет неуспешно, Termite покажет либо исключение (т.е. ситуацию, при которой возникла ошибка), либо трассировку стека (т.е. список функций, которые были вызваны до момента, когда в скетче произошла ошибка), либо исключение и трассировку стека вместе.

В результате в логах может появиться примерно следующее:

Если у вас возникла такая ошибка, то ESP8266, скорее всего, не был перезагружен после первой загрузки скетча (через последовательный порт).

Самые распространенные причины неуспешного выполнения OTA-апдейта:

  • Чипу не достает flash-памяти (например, у ESP01 только 512 килобайт flash-памяти, которых недостаточно для OTA-апдейта)
  • Для SPIFFS объявлено слишком много памяти, поэтому скетчу недостаточно места, чтобы поместиться между старым скетчем и SPIFFS (подробнее смотрите ниже, в разделе «Разбивка памяти во время OTA-апдейта»)
  • В IDE Arduino объявлено слишком мало памяти для выбранной платы (т.е. объявленная память меньше flash-памяти платы)
  • ESP8266 не был перезагружен после загрузки первого скетча (через последовательный порт)

Более подробно о разбивке flash-памяти читайте в статье о файловой системе. О том, как во время OTA-апдейта реорганизуется flash-память (включая то, как сохраняется и копируется новый скетч), читайте ниже, в разделе «Разбивка памяти во время OTA-апдейта».

OTA-апдейт через веб-браузер

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

  • После того, как скетч был установлен, и если использовать IDE Arduino по какой-то причине неудобно или даже невозможно
  • После того, как скетч был установлен, и если пользователь не может сделать ESP8266 видимым для OTA-апдейта через внешний апдейтный сервер
  • Чтобы обновлять небольшое количество ESP8266 после того, как на них были установлены скетчи, и если настройка апдейтного сервера неосуществима

Требования

  • ESP8266 и ПК должны быть подключены к одной и той же сети

Как реализовать OTA-апдейт в скетче (вкратце)

OTA-апдейт через браузер осуществляется при помощи класса ESP8266HTTPUpdateServer совместно с классами ESP8266WebServer и ESP8266mDNS. Чтобы все это заработало, понадобится следующий код:

Блок setup()

MDNS.begin(host);

httpUpdater.setup(&httpServer);
httpServer.begin();

MDNS.addService("http", "tcp", 80);

Блок loop()

httpServer.handleClient();

Выполнение OTA-апдейта

Для OTA-апдейта при помощи браузера понадобится следующее:

  • Скетч-пример «WebUpdater.ino» для библиотеки ESP8266HTTPUpdateServer
  • Плата NodeMCU 1.0 (с модулем ESP-12E)

Можно использовать и другую плату, если она соответствует требованиям, указанным выше, в разделе «Базовые требования».

1) Убедитесь, что у вас установлено следующее ПО:

  • IDE Arduino
  • Аддон ESP8266 для IDE Arduino версии 2.0.0-rc1 (от 17 ноября 2015 года). Инструкцию по установке читайте читайте тут).
  • Хост-программа. Она будет разной в зависимости от ОС: на LinuxAvahi, на Windows – Bonjour. В MacOS и iOS этот функционал встроен по умолчанию, поэтому никакого дополнительного ПО не требуется.

2) Подготовьте скетч и IDE Arduino для первой загрузки через последовательный порт.

  • Запустите IDE Arduino и откройте скетч «WebUpdater.ino», кликнув на Файл > Примеры > ESP8266HTTPUpdateServer > WebUpdater (File > Examples > ESP8266HTTPUpdateServer > WebUpdater).
  • Укажите в скетче SSID и пароль своей WiFi-сети, чтобы ESP8266 мог к ней подключиться.
  • Кликните в IDE Arduino на Файл > Настройки (File > Preferences) и поставьте галочку на пункте «Показать подробный вывод: Компиляция» («Show verbose output during: compilation»).

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

3) Загрузите скетч ( Ctrl + U ). Загрузив, откройте монитор порта ( Ctrl + ⇧ Shift + M ) и проверьте, появилось ли в нем сообщение, показанное на картинке ниже. Оно содержит ссылку OTA-апдейта.

Примечание: Это сообщение появится только после того, как ESP8266 успешно подключится к сети и будет готов к OTA-апдейту. Не забудьте перенастроить ESP8266 после загрузки по последовательному порту, о котором рассказывалось в 3 шаге главы об OTA-апдейте при помощи IDE Arduino.

4) Теперь откройте браузер и введите туда URL, показанный в мониторе порта, т.е. «http://esp8266-webupdate.local/update». После этого в браузере должна появиться страница вроде той, что показана на картинке ниже. Эта страница обслуживается ресурсами ESP8266 и предлагает выбрать файл для OTA-апдейта.

Примечание: Если ссылка «http://esp8266-webupdate.local/update» не заработает, попробуйте заменить «esp8266-webupdate» на IP-адрес ESP8266. К примеру, если этот IP-адрес«192.168.1.100», ссылка должна быть «http://192.168.1.100/update». Это решение на тот случай, если хост-программа, установленная в 1 шаге, не работает. Если веб-страница все равно не появляется, и в мониторе порта нет ни единого намека почему, попробуйте определить проблему, открыв этот URL в Google Chrome, нажав  F12 , а затем проверив вкладки «Console» и «Network» – в них печатаются дополнительные логи, которые могут помочь в решении проблемы.

5) Чтобы получить нужный файл, откройте папку, в которую IDE Arduino сохраняет результаты компиляции. Путь к нужному файлу есть в логах IDE Arduino (см. картинку ниже).

6) Нажмите на кнопку «Choose File» в браузере, перейдите в папку, которую определили в 5 шаге, найдите файл «WebUpdater.cpp.bin» и загрузите его. Если загрузка пройдет успешно, в браузере появится сообщение «OK».

ESP8266 перезагрузится, что будет видно в мониторе порта.

После перезагрузки в мониторе порта появится точно такое же сообщение, как и в 3 шаге, то есть «HTTPUpdateServer ready! Open http:// esp8266-webupdate.local /update in your browser». Это произойдет, потому что ESP8266 снова загрузится с тем же кодом: сначала через последовательный порт, а теперь – через OTA. Разобравшись с этой процедурой, попробуйте модифицировать скетч «WebUpdater.ino» (чтобы он печатал какие-нибудь дополнительные сообщения), скомпилируйте его, найдите бинарный файл этого скетча и загрузите его в браузере. Монитор порта должен отобразить введенные изменения.

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

Если после модификации скетча OTA-апдейт пройдет неуспешно, ESP8266 всегда можно восстановить загрузкой скетча через последовательный порт. После этого продиагностируйте проблему при помощи монитора порта. Исправив проблему, снова попробуйте выполнить OTA-апдейт.

OTA-апдейт через HTTP-сервер

Класс ESPhttpUpdate позволяет проверять наличие обновлений, а затем загружать эти обновления (в виде бинарных файлов) с HTTP-сервера. С его помощью обновления можно загружать с любого IP-адреса или доменного имени в интернете.

Требования

Код для IDE Arduino

OTA-апдейт через HTTP-сервер можно сделать двумя разными способами – простым и продвинутым.

Простой способ

Простой апдейтер загружает файл с каждым вызовом апдейтной функции:

ESPhttpUpdate.update("192.168.0.2", 80, "/arduino.bin");

Продвинутый способ

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

Серверный скрипт может ответить по-разному. Во-первых, он может прислать код «200» и выслать образ прошивки, а во-вторых, ответить кодом «304», и это будет значить, что ESP8266 обновление не требуется.

t_httpUpdate_return ret = ESPhttpUpdate.update("192.168.0.2", 80, "/esp/update/arduino.php", "здесь опциональный аргумент с версией");
switch(ret) {
    case HTTP_UPDATE_FAILED:
        Serial.println("[update] Update failed.");
        break;
    case HTTP_UPDATE_NO_UPDATES:
        Serial.println("[update] Update no Update.");
        break;
    case HTTP_UPDATE_OK:
        Serial.println("[update] Update ok."); // may not called we reboot the ESP
        break;
}

Обработка запроса сервером

В простом и продвинутом способах обработка запроса сервером выполняется по-разному.

Простой способ

В этом случае сервер лишь отправляет отправить бинарный файл прошивки.

Продвинутый способ

В этом случае серверу нужно запустить скрипт (например, PHP-скрипт), обрабатывающий информацию от ESP8266. С каждым запросом ESP8266 отправляет серверу несколько HTTP-заголовков, содержащих информацию вроде MAC-адреса, свободного места, размера скетча и пр.

Вот пример данных, присылаемых от ESP8266:

[HTTP_USER_AGENT] => ESP8266-http-Update
[HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_AP_MAC] => 1A:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_FREE_SPACE] => 671744
[HTTP_X_ESP8266_SKETCH_SIZE] => 373940
[HTTP_X_ESP8266_SKETCH_MD5] => a56f8ef78a0bebd812f62067daf1408a
[HTTP_X_ESP8266_CHIP_SIZE] => 4194304
[HTTP_X_ESP8266_SDK_VERSION] => 1.3.0
[HTTP_X_ESP8266_VERSION] => DOOR-7-g14f53a19

На основе этой информации скрипт должен понять, нужно ли вообще проводить апдейт ESP8266. Кроме того, в зависимости от MAC-адреса можно отправлять ESP8266 разные бинарные прошивки.

Пример скрипта:

<?PHP

header('Content-type: text/plain; charset=utf8', true);

function check_header($name, $value = false) {
    if(!isset($_SERVER[$name])) {
        return false;
    }
    if($value && $_SERVER[$name] != $value) {
        return false;
    }
    return true;
}

function sendFile($path) {
    header($_SERVER["SERVER_PROTOCOL"].' 200 OK', true, 200);
    header('Content-Type: application/octet-stream', true);
    header('Content-Disposition: attachment; filename='.basename($path));
    header('Content-Length: '.filesize($path), true);
    header('x-MD5: '.md5_file($path), true);
    readfile($path);
}

if(!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater!\n";
    exit();
}

if(
    !check_header('HTTP_X_ESP8266_STA_MAC') ||
    !check_header('HTTP_X_ESP8266_AP_MAC') ||
    !check_header('HTTP_X_ESP8266_FREE_SPACE') ||
    !check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
    !check_header('HTTP_X_ESP8266_SKETCH_MD5') ||
    !check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
    !check_header('HTTP_X_ESP8266_SDK_VERSION')
) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater! (header)\n";
    exit();
}

$db = array(
    "18:FE:AA:AA:AA:AA" => "DOOR-7-g14f53a19",
    "18:FE:AA:AA:AA:BB" => "TEMP-1.0.0"
);

if(!isset($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']])) {
    header($_SERVER["SERVER_PROTOCOL"].' 500 ESP MAC not configured for updates', true, 500);
}

$localBinary = "./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']].".bin";

// проверяем, прислал ли ESP8266 версию прошивки;
// если она не соответствует, проверяем соответствие MD5-хэшэй между 
// бинарным файлом на сервере и бинарным файлом на ESP8266;
// если они не соответствуют, то апдейта выполнено не будет:
if((!check_header('HTTP_X_ESP8266_SDK_VERSION') && $db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION'])
    || $_SERVER["HTTP_X_ESP8266_SKETCH_MD5"] != md5_file($localBinary)) {
    sendFile($localBinary);
} else {
    header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
}

header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);

Класс Stream

Разработчики еще не сделали документацию к этому разделу.

Класс Stream – это базовый класс для всех типов обновления, будь то OTA, клиент/сервер и т.д.

Класс Updater

Класс Updater скрыт внутри ядра и используется для записи прошивки на flash-память, проверки целостности данных, а также для того, чтобы скомандовать загрузчику, чтобы он загрузил новую прошивку при следующем запуске ESP8266.

Процесс обновления – как реорганизуется память

  • Новый скетч будет сохранен между старым скетчем и SPIFF
  • При следующей перезагрузке загрузчик («eboot») сверяется с командами
  • Новый скетч копируется поверх старого
  • Новый скетч запускается

См.также

Внешние ссылки