OTA Updates

来自YFRobotwiki
跳转至: 导航搜索

最新原文文档地址:ESP8266 Arduino Core-latest version


介绍 Introduction

OTA(空中)更新是使用Wi-Fi连接而不是串行端口将固件加载到ESP模块的过程。在对模块进行有限或无物理访问的情况下,这种功能变得非常有用。

OTA需要一下几个方面的支持:

  • Arduino IDE
  • Web Browser
  • HTTP Server

Arduino IDE选项主要用于软件开发阶段。 另外两个选项将在部署后更有用,通过Web浏览器手动提供应用程序更新模块,或者自动使用http服务器。 在任何情况下,必须通过串行端口完成第一个固件上传。 如果OTA例程在草图中正确实现,则所有后续上传都可以在空中完成。

OTA进程没有强加的安全性被黑客入侵。确保开发人员只能从合法/受信任的来源获得更新。更新完成后,模块将重新启动,并执行新的代码。开发人员应确保在模块上运行的应用程序以安全的方式关闭并重新启动。以下章节提供有关OTA过程的安全性和安全性的其他信息。

保密性 Security

模块必须以无线方式显示,以便通过新的草图进行更新。 这使得模块被强行入侵并加载了其他代码。 为了减少被黑客入侵的可能性,请考虑使用密码保护您的上传,选择某些OTA端口等。

检查可以提高安全性的ArduinoOTA库提供的功能:

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

已经内置了某些保护功能,不需要开发人员进行任何其他编码。ArduinoOTA和espota.py使用Digest-MD5来验证上传。使用MD5校验和,在ESP端验证传输数据的完整性。

进行自己的风险分析,并根据应用决定什么库功能来实现。如果需要,请考虑实施其他保护手段被黑客入侵。仅根据具体时间安排上传的模块,触发OTA只能按用户专用的“更新”按钮连接到ESP等。

安全性 Safety

OTA过程在上传过程中采用ESP的资源和带宽。然后重新启动模块并执行新的草图。分析和测试它如何影响现有和新草图的功能。

如果将ESP放置在远程位置并控制某些设备,则应该额外注意如果本设备的操作突然被更新过程中断,会发生什么。因此,在开始更新之前,请决定如何将本设备置于安全状态。例如,您的模块可能会按顺序控制花园浇水系统。如果这个顺序没有正确关闭并且水阀打开,你的花园可能会被淹没。

ArduinoOTA库提供以下功能,旨在处理OTA特定阶段应用程序的功能或OTA错误:

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

基本要求 Basic Requirements

闪存芯片尺寸应该能够同时保持旧的草图(当前正在运行)和新的草图(OTA)。

请记住文件系统和EEPROM例如需要的空间(一次)也看到闪光布局。

ESP.getFreeSketchSpace();

可用于检查新草图的可用空间。

有关内存布局的概述,存储新草图以及在OTA过程中如何复制它们,请参阅更新进程 - 内存视图

以下章节提供了更多的细节和具体的OTA做法。

Arduino IDE

从Arduino IDE无线上传模块适用于以下典型场景: - 在固件开发过程中,通过串行加载更快的替代方案 - 用于更新少量模块 - 只有模块在与Arduino IDE的计算机相同的网络上可用。

要求 Requirements

  • ESP和计算机必须连接到同一个网络。

应用实例 Application Example

以下说明在NodeMCU 1.0(ESP-12E Module)板上配置OTA。你可以使用任何其他董事假定其符合要求,如上所述。该指令适用于Arduino IDE支持的所有操作系统。在Windows 7上进行了屏幕截图,如果您使用的是Linux和MacOS,您可能会看到较小的差异(如串行端口名称)。

1.在开始之前,请确保您安装了以下s / w:

- Arduino IDE 1.6.7或更高版本 - https://www.arduino.cc/en/Main/Software

- esp8266 / Arduino平台软件包2.0.0或更新 - 有关说明请遵循 https://github.com/esp8266/Arduino#installing-with-boards-manager

- Python 2.7(不安装不支持的Python 3.5) - https://www.python.org/

注意: Windows用户应选择“将python.exe添加到路径”(见下文 - 默认情况下未选择此选项)。

fetch

2.现在准备通过串行端口上传的草图和配置。 - 启动Arduino IDE并加载草图BasicOTA.ino可在File> Examples> ArduinoOTA下找到

fetch1

- 在草图中更新SSID和密码,以便模块可以加入您的Wi-Fi网络

fetch2

- 配置上传参数如下(如果使用不同的模块,可能需要调整配置):

fetch3


注意:根据平台包和板的版本,您可能会 Upload Using: 在上面的菜单中看到。此选项不活动,您选择的内容并不重要。它已经与旧版OTA实现兼容,目标是在平台软件包版本2.2.0中进行删除。


3.上传草图(Ctrl + U)。完成后,打开串行监视器(Ctrl + Shift + M)并检查模块是否已加入Wi-Fi网络:

fetch4

只有模块连接到网络,几秒钟后,esp8266- ota端口将显示在Arduino IDE中。选择串行监视器中显示的IP地址的端口,步骤如下:

fetch5

注意:如果OTA端口没有出现,请退出Arduino IDE,再次打开并检查端口是否存在。如果没有帮助检查您的防火墙设置。


4.现在通过选择OTA端口为您的第一个OTA上传做好准备:

fetch6

注意:菜单条目 Upload Speed: 在这一点上并不重要,因为它涉及串行端口。只是保持不变。

5.如果您已成功完成上述所有步骤,您可以通过OTA上传(Ctrl + U)相同(或任何其他)草图:

fetch7

注意:为了能够一遍又一遍地使用OTA上传草图,您需要在其中嵌入OTA例程。请以BasicOTA.ino为例。


密码保护

使用密码 保护您的OTA上传是非常简单的。所有你需要做的,是在你的代码中包括以下语句:

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

其中123是您应该用自己替换的样本密码。

在草图中实现之前,最好使用 File > Examples > ArduinoOTA 下的BasicOTA.ino草图来检查它的工作原理。继续,打开BasicOTA.ino,取消注释已经存在的上述语句,并上传草图。为了使故障排除更容易,除了绝对需要的外,不要修改示例草图。这包括原始简单的OTA密码。然后尝试再次上传草图(使用OTA)。编译完成后,一旦上传即将开始,您将看到如下提示输入密码:123

fetch8

输入密码,上传应该像往常一样启动,唯一的区别是 Authenticating...OK 消息在上传日志中可见。

fetch9

下次不会提示您重新输入相同的密码。Arduino IDE会为您记住它。只有在重新打开IDE之后,才会看到提示输入密码,或者如果您在草图中更改密码,请上传草图,然后尝试重新上传。

请注意,如果IDE自上次上传以来尚未关闭,可以显示以前在Arduino IDE中输入的密码。这可以通过在“文件”>“首选项”中上传,并尝试上传模块来启用“ 显示详细”输出。

fetch10

上图显示了密码在日志中可见,因为它被传递给espota.py上传脚本。

下面的另一个例子显示了在上传之间更改密码时的情况。

fetch11

上传时,Arduino IDE使用以前输入的密码,因此上传失败,并已由IDE清楚报告。只有IDE才提示输入新密码。正确输入,第二次上传尝试已成功。


故障排除

如果OTA更新失败,首先要检查可能在Arduino IDE的上传窗口中显示的错误消息。如果没有提供任何有用的提示,请尝试在检查ESP在串行端口上显示的内容时再次上传。在这种情况下,IDE的串行监视器将不会有用。尝试打开它时,您可能会看到以下内容:

fetch12

这个窗口是为ArduinoYún而尚未实现的esp8266 / Arduino。它出现,因为IDE尝试使用您为OTA上传选择的网络端口打开串行监视器。

相反,您需要一个外部串行监视器。如果您是Windows用户,请查看Termite。这是方便,光滑和简单的RS232端子,不强制RTS或DTR流量控制。如果使用各自的线路切换ESP上的GPIO0和RESET引脚进行上传,则此类流量控制可能会导致问题。

在外部终端程序中选择COM端口和波特率,就像使用Arduino串行监视器一样。请参阅以下Termite的典型设置:

fetch13

然后从IDE 运行OTA,看看终端上显示的内容。使用BasicOTA.ino草图的成功ArduinoOTA过程如下所示(IP地址取决于您的网络配置):

fetch14

如果上传失败,您可能会看到上传者捕获的错误,异常和堆栈转储,或两者兼而有之。

OTA故障 的最常见原因如下:*芯片上没有足够的物理内存(例如,具有512K闪存的ESP01,对于OTA来说不够),*为SPIFFS指定了太多的内存,因此新的草图将不适合现有的草图和SPIFFS - 请参阅 更新过程 - 内存视图,*在Arduino IDE中为您选定的电路板声明的内存太少(即小于物理大小)。

有关闪存布局的更多详细信息,请检查文件系统。有关存储新草图的概述,如何复制以及如何为OTA目的组织内存,请参阅更新进程 - 内存视图


网页浏览器 Web Browser

本章中描述的更新使用可在以下典型场景中使用的Web浏览器:

  • 应用程序部署后,直接从Arduino IDE加载是不方便或不可能的
  • 部署后,如果用户无法从外部更新服务器公开OTA的模块
  • 在设置更新服务器不可行时,将部署后的更新提供给少量模块

要求 Requirements

  • ESP和计算机必须连接到同一个网络。

实施概况 Implementation Overview

使用Web浏览器的更新是使用 ESP8266HTTPUpdateServer 类 ESP8266WebServer 和 ESP8266mDNS 类一起实现的。需要以下代码才能使其工作:

setup()

	MDNS.begin(host);
 
	httpUpdater.setup(&httpServer);
	httpServer.begin();
 
	MDNS.addService("http", "tcp", 80);


loop()

        httpServer.handleClient();


应用例程 Application Example

以下提供的示例实现使用:

  • ESP8266HTTPUpdateServer 库中的示例草图WebUpdater.ino
  • NodeMCU 1.0(ESP-12E模块)

如果符合先前desribed您可以使用另一个模块的要求。

1.在开始之前,请确保您已安装以下软件:

- Arduino IDE和2.0.0-rc1(2015年11月17日)版本的平台包,如 https://github.com/esp8266/Arduino#安装与板管理器

- 主机软件取决于您使用的O / S:

a. Avahi http://avahi.org/ for Linux
b. Bonjour http://www.apple.com/support/bonjour/ for Windows
c. Mac OSX和iOS - 支持已经内置/不需要任何额外的s / w

2.使用串行端口准备草图和配置以进行初始上传。

- 启动Arduino IDE并加载草图WebUpdater.ino,可在File> Examples> ESP8266HTTPUpdateServer中找到。

- 在草图中更新SSID和密码,以便模块可以加入您的Wi-Fi网络。

- 打开文件>首选项,查找“显示详细输出期间:/ Show verbose output during:”,并查看“编译/complation”选项。

fetch15

注意:在下面的步骤5中将需要此设置。之后,您可以取消选中此设置。

3.上传草图(Ctrl + U)。完成打开串行监视器(Ctrl + Shift + M)并检查是否看到显示以下消息,其中包含OTA更新的URL 。

fetch16

注意:只有模块成功加入网络并准备进行OTA上传后,才会显示此类消息。

4.现在打开Web浏览器并输入Serial Monitor提供的URL,即 http://esp8266-webupdate.local/update。一旦输入,浏览器应该显示下面由您的模块提供的表单。表单邀请您选择要更新的文件。

fetch17

注意:如果输入 http://esp8266-webupdate.local/update 不起作用,请尝试 esp8266-webupdate 使用模块的IP地址替换。例如,如果你的模块IP是 192.168.1.100 url应该是 http://192.168.1.100/update 。如果步骤2中安装的主机软件不起作用,此解决方法很有用。如果仍然没有任何工作,串行监视器上没有任何线索,请尝试通过在Google Chrome中打开提供的网址来诊断问题,然后按F12并检查“控制台”和“网络”选项卡的内容。Chrome在这些标签上提供了一些高级日志记录。

5.要获取文件导航到Arduino IDE使用的目录来存储编译结果。您可以在IDE调试窗口中显示的编译日志中检查此文件的路径,如下所示。

fetch18

6.现在在网络浏览器中按“选择文件”,进入上述步骤5中找到的目录,找到文件“WebUpdater.cpp.bin”并上传。如果上传成功,您将在下面的Web浏览器中看到“OK”。

fetch19

模块将重新启动,应该在串行监视器上可见:

fetch20

重新启动后,您应该看到完全相同的消息, HTTPUpdateServer ready! Open http:// esp8266-webupdate.local /update in your browser如步骤3.这是因为模块已重新加载相同的代码 - 首先使用串行端口,然后使用OTA。

一旦你对这个程序感到舒服,就可以修改WebUpdater.ino草图来打印一些额外的消息,编译它,找到新的二进制文件并使用Web浏览器上传,以便在串行监视器上查看输入的更改。

您还可以按照上述实施概述中的准则,将OTA例程添加到您自己的草图中。如果这样做正确,您应该总是能够使用Web浏览器上传新的草图。

如果在草图中输入修改后OTA更新失败,您可以随时通过将其加载到串行端口来恢复模块。然后使用串行监视器用草图诊断问题。一旦问题被修复,再次尝试OTA。


HTTP服务器

ESPhttpUpdate类可以检查更新并从HTTP Web服务器下载二进制文件。可以从网络或Internet上的每个IP或域名地址下载更新。


要求

- 网络服务器


Arduino代码

简单的更新程序

简单的更新程序每次调用函数时都会下载该文件。

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

高级更新器

它可以将更新功能指向服务器上的脚本。如果给出版本字符串参数,它将被发送到服务器。服务器端脚本可以使用它来检查是否应该执行更新。

服务器端脚本可以如下响应: - 响应代码200,并发送固件映像,或响应代码304,通知ESP,不需要更新。

t_httpUpdate_return ret = ESPhttpUpdate.update("192.168.0.2", 80, "/esp/update/arduino.php", "optional current version string here");
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脚本。在每次更新请求时,ESP将HTTP头中的一些信息发送到服务器。

标题数据示例:

    [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_CHIP_SIZE] => 4194304
    [HTTP_X_ESP8266_SDK_VERSION] => 1.3.0
    [HTTP_X_ESP8266_VERSION] => DOOR-7- g14f53a19

有了这个信息,脚本现在可以检查是否需要更新。例如,也可以根据MAC地址传送不同的二进制文件。

脚本示例:


<?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_CHIP_SIZE') ||
	!check_header('HTTP_X_ESP8266_SDK_VERSION') ||
	!check_header('HTTP_X_ESP8266_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']])) {
	if($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION']) {
		sendFile("./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']]."bin");
	} else {
		header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
	}
	exit();
}
 
header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);

流接口 Stream Interface

TODO描述流界面

流接口是所有其他更新模式(如OTA,http服务器/客户端)的基础。


更新器类 Updater class

更新程序在Core中,处理将固件写入闪存,检查其完整性,并告知Bootloader在下次启动时加载新固件。

更新进程 - 内存视图 Update process - memory view

  • 新草图将存储在旧素描和螺纹之间的空间中。
  • 在下次重新启动时,“eboot”引导程序检查命令。
  • 新的草图现在被复制“旧”。
  • 新草图开始了。

fetch21




给我写信

返回ESP8266_Arduino

返回首页

购买地址 arduino_ESP8266

更多建议和问题欢迎反馈至 YFRobot论坛