ESP32 教程:ESP32 的安全 OTA 更新

这是我们之前的博客文章 “无线更新 ESP32” 的后续文章。 我们已经实施了一个新版本的 OTA 示例,并进行了各种改进:

  • 在最初的版本中,您必须将固件更新 “推(push)” 到特定设备。现在,设备会定期连接到 Web 服务器以检查是否有可用的更新,如果是,请下载并安装它。 这使得更容易自动更新大量的设备。
  • 在最初的版本中,使用普通的 HTTP 传输固件镜像。 我们现在使用带有证书锁定的 HTTPS 来确保设备,只从受信任的服务器下载固件。

该图显示了一个典型的场景:

ESP32 OTA 更新

Web 服务器提供两个文件。

  • 第一个是一个文本文件,包含有关可用更新的元信息(在哪里可以找到它以及具有哪个版本)以及设备用于检查新更新的轮询间隔。我们使用一个简单的整数来标识版本(1, 2 ,3等)。
  • 第二个文件是实际的固件二进制文件。 如果设备检测到服务器上的固件版本与其运行的版本不同,则会下载并安装固件。

我们正在研究另一篇后续文章,介绍如何将此机制与 ESP32 的安全引导加载程序基础结构集成。在这篇文章中,我们忽略了这个方面。 我们也忽略了一个事实,即您可能想验证客户端访问固件。

新示例中的代码被分成多个模块,以便更容易理解并集成到实际的应用程序中。例如,应用程序的其他部分可能需要执行 HTTP 请求。现在他们可以这样做了,因为 HTTP 请求的代码在它自己的独立模块中。 或者您可能需要通过蓝牙或 USART 更新设备。 在这种情况下,您可以简单地重新使用 IAP 模块。

ESP32 OTA 架构

iap_https 模块包含了协调固件更新的实际逻辑。大多数时候,它在 sleep,等待请求查询服务器的更新。我们支持两种类型的请求,自动定期请求(由 FreeRTOS 定时器触发)和手动请求。

如果请求到达,iap_https 模块使用 wifi_tls 模块连接到 Web 服务器,并使用 https_client 模块发送 GET 请求以获取元信息文件。它将元信息文件中收到的版本与安装的软件版本进行比较。 如果两个版本不同,则使用 https_client 模块从服务器下载固件映像,并在 iap 模块的帮助下将其写入闪存。

开始使用示例代码

从我们的 GitHub 仓库上下载示例代码(https://github.com/classycodeoss/esp32-ota-https),选择 1.0 标签。我们已经用当前版本的 ESP-IDF 测试了这个版本,所以如果你遇到编译错误而不想修复它们,或者如果这个例子不起作用,你可能想试试从 02/08/2017 左右的 ESP-IDF 个版本,例如 提交 c61fdff7293c68142d052376eace1a3a9f6a2312

首先,您需要为 HTTPS 设置一个 Web 服务器,您可以在其中存储元信息和固件镜像文件。

  • 元信息文件是一个简单的键值文本文件,拥有 3 行内容(固件映像的路径,固件版本,轮询间隔(秒))。 首先,将 main.h 中放置相同的版本号,以便应用程序连接到服务器,但不执行软件更新。

OTA 元数据示例

  • 固件镜像是在 ESP32 构建过程中生成的 “bin” 文件。确保文件名与元信息文件中的名称匹配。

在服务器上安装 SSL 证书以使 HTTPS 正常工作。证书可以自签名。将根 CA 证书和对等(peer)证书的内容放在 main.h 中(当然没有私钥!):

接下来,更新 main.h 中的剩余配置:

  • WIFI_NETWORK_SSID 和 WIFI_NETWORK_PASSWORD 在 main.h 中被硬编码。或者,您可以在 main.c 中的 init_wifi 函数中提供它。
  • 元数据文件的服务器主机名和路径也在 main.h 中配置。更新您的 Web 服务器安装的值。
  • OTA_POLLING_INTERVAL_S 定义了应用程序用来轮询 Web 服务器固件更新的时间间隔。如果要手动触发这些请求,请将该值设置为0。
  • OTA_AUTO_REBOOT 定义了下载并安装 iap_https 模块后是否应该自动重新启动到新的固件。如果您希望在特定的地方手动触发重新启动,请将其设置为0。如在 main 任务中。查询 iap_https_new_firmware_installed 功能,检查是否已经下载并安装了新的固件镜像,但尚未启动。

在构建示例之前,运行 make menuconfig为您的环境做准备(初始串行闪存的设备和波特率)。可能是将日志级别更改为 DEBUG,直到一切正常。

选择带有一个工厂和两个 OTA 分区的分区表:

分区表

在 FreeRTOS 设置中,您需要将 FreeRTOS 限制为使用当前版本的 ESP-IDF 在单个内核上运行以及示例代码:

FreeRTOS 设置

(如果 FreeRTOS 在两个内核上运行,目前有一个竞争条件可能导致闪存写入挂起或崩溃(可能与此错误报告中描述的问题相同),我将在修复此博客文章时进行更新。)

构建并烧录示例程序。 日志输出应该如下所示:

日志示例

修复出现的任何错误。

提供更新的固件映像

main.h 中的 SOFTWARE_VERSION 从 1 增加到 2,然后再次构建应用程序。不要烧录,因为我们现在要测试 OTA 更新!

esp32-ota-https.bin 文件传输到您的 Web 服务器。更新文件名和新软件版本的元信息文件,然后保存元信息文件。

几秒钟后(取决于您在 main.h 中为 OTA_POLLING_INTERVAL定义的内容),应用程序应检测到新的固件版本可用,并应开始下载并安装它:

OTA 示例

如果 main.h 中的 OTA_AUTO_REBOOT 设置为 1,应用程序应该自动重新启动 ESP32。

我们希望这对你有用。 在评论中留下您的反馈:-)

原文链接:https://blog.classycode.com/secure-over-the-air-updates-for-esp32-ec25ae00db43

尚未评分
您的评分将帮助我们做出更好的玩法

观光\评论区

Copyright © 2017 玩点什么. All Rights Reserved.