在 Espressif ESP32 上测试 OTA

以下说明使用 Matter SDK 中的照明应用示例以及 M5Stack ESP32 开发板。

构建环境设置

首先,克隆 Matter SDK。

在此示例中,我们查看了 Google Home 的 Matter 版本 5 支持的最低提交内容:

$ mkdir otaprep
$ cd otaprep
git clone https://github.com/project-chip/connectedhomeip.git
cd connectedhomeip
git fetch origin v1.0-branch
git checkout FETCH_HEAD
git submodule update --init --recursive
source ./scripts/activate.sh

接下来,我们会检查 ESP32 GitHub 工作流中使用的版本,以确定哪个 Docker 映像最适合我们的构建:

$ cat .github/workflows/examples-esp32.yaml | grep chip-build | head -n 1
            image: connectedhomeip/chip-build-esp32:0.5.99

我们从 Docker 映像运行容器,并传递标志以将 Matter SDK 装载到容器中并提供对 ESP32 设备的访问权限。

$ docker run --name container_name -it --user $(id -u):$(id -g) --mount source=$(pwd),target=/workspace,type=bind --device=/dev/ttyUSB0 connectedhomeip/chip-build-esp32:0.5.99 /bin/bash

停止和启动 Matter Docker 容器

每当运行 docker run 命令时,您都会使用指定映像创建一个新容器。当您执行此操作时,保存在上一个容器实例上的旧数据将丢失。有时,您可能会出现这种情况,因为它允许您从头开始安装。但在此示例中,您最有可能希望在会话之间保存工作和环境配置。

user@host> docker stop container_name

当您准备好再次运行时,请启动容器并打开一个终端窗口:

user@host> docker start container_name
user@host> docker exec -it container_name /bin/bash

您可以使用以下命令打开与您的容器的其他终端会话:

user@host> docker exec -it container_name /bin/bash

或者使用以下命令启动根会话:

user@host> docker exec -u 0 -it container_name /bin/bash

初始化 SDK

在容器中,我们初始化 Matter SDK 和 ESP IDF:

cd /workspace
git submodule update --init --recursive
source ./scripts/activate.sh
source /opt/espressif/esp-idf/export.sh

构建并刷写

下一个任务是构建映像并刷写开发套件以接收 Matter OTA 固件更新。

为此,您必须创建映像。

首先,使用 ESP IDF 中的 menuconfig 实用程序配置 build。

cd examples/lighting-app/esp32
idf.py menuconfig

在交互式菜单中,配置以下设置:

  1. Component config --->

  2. CHIP Device Layer --->

  3. Device Identification Options --->

  4. Vendor ID 设置为由 Connectivity Standards Alliance (Alliance) 分配的 VID。

  5. Product ID 设置为您在 Google Home Developer Console 中的 Matter 集成中设置的 PID。

启用 OTA 请求者标志:

  1. Component config -->

  2. CHIP Core -->

  3. System options --->

  4. 启用 OTA 请求者标志 [*] Enable OTA Requestor

  5. 按两次 ESC 可返回顶级菜单。

启用 Matter OTA 映像创建标志:

  1. Component config -->

  2. CHIP Device Layer --->

  3. Matter OTA Image --->

  4. [*] Generate OTA IMAGE

设置版本号:

  1. Application manager --->

  2. 选择[*] Get the project version from Kconfig

  3. Project version (NEW) 设置为 1.0

  4. s 保存配置,按 Enter 两次,然后按 q 退出 menuconfig

设置测试证书

按照创建 Matter 设备测试证书中的步骤创建 CD、DAC 和 PAI 证书。

打造设备

现在,运行 build 并刷写设备:

idf.py build
idf.py -p /dev/ttyUSB0 erase_flash
idf.py -p /dev/ttyUSB0 flash

创建并上传 OTA 映像

现在,再次更改构建设置以创建 OTA 映像。使用相同的映像,但版本号递增。

运行 menuconfig

idf.py menuconfig

在交互式菜单中,更新以下内容:

  1. Application manager --->
  2. 选择[*] Get the project version from Kconfig
  3. Project version (NEW) 设置为 2.0
  4. s 保存配置,按 Enter 两次,然后按 q 退出 menuconfig

构建和检索映像。下面的示例演示了该映像用于 OTA 的位置以及使用 ota_image_tool.py 解析时的输出。

cd build
/workspace/src/app/ota_image_tool.py show ./chip-lighting-app-ota.bin
Magic: 1beef11e
Total Size: 1243360
Header Size: 64
Header TLV:
  [0] Vendor Id: XXXXX (0x000)
  [1] Product Id: XXXXX (0x000)
  [2] Version: 2 (0x2)
  [3] Version String: v2.0
  [4] Payload Size: 1243280 (0x12f890)
  [8] Digest Type: 1 (0x1)
  [9] Digest: e367f4d71e2ccd554b9a399c864abbf2c039382ef1def1b986fb2f59a99923a8

由于 Matter SDK 是从容器主机装载的,因此 OTA 映像在您的容器主机上可用。

按照 OTA 上传说明将 OTA 映像上传到 Developer Console

调试到 Google Home 并观察 OTA

确保您的设备已通过 USB 连接到 Linux 主机。以下示例展示了如何使用 GNU screen 读取设备日志:

screen -L /dev/ttyUSB0 115200

这会显示从设备到终端的输出,并将相同的输出写入名为 screenlog.0 的默认屏幕日志文件。

您可以在其他文本编辑器中打开 screenlog.0 文件,也可以使用 cattailmoregrep 在其他 shell 中显示该文件。

按设备侧面的红色重置按钮,查看启动日志。

在设备输出中,您应该会看到之前设置的 VID 和 PID,以及用于调试设备的二维码图片的网址。

[0;32mI (2388) chip[DIS]: Advertise commission parameter vendorID=XXXXX productID=XXXX discriminator=3840/15 cm=1[0m

[0;32mI (1928) chip[SVR]: SetupQRCode: [MT:E59-000000000000000][0m

https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3AE59-000000000000000

确保您的 Hub 在家中已联网。

使用日志文件中显示的链接中的二维码,通过 Google Home app (GHA) 调试设备。

让设备在调试后几分钟不间断运行。您应该观察与 OTA 请求程序、OTA 映像下载和 OTAImageProcessor 相关的日志输出。

安装映像后,请观察该映像的编译时间与上传到控制台的映像的编译时间一致,并且晚于首次启动时报告的编译时间。在正则表达式模式下在 screenlog.0 上使用以下模式执行 grep 可以说明 OTA 流程:

$ grep -E "(Compile time|OTA)" screenlog.0
I (76) boot:  1 otadata          OTA data         01 00 0000f000 00002000
I (91) boot:  3 ota_0            OTA app          00 10 00020000 00177000
I (99) boot:  4 ota_1            OTA app          00 11 001a0000 00177000
I (645) cpu_start: Compile time:     Oct 15 2022 06:21:59
I (135558) chip[SWU]: OTA Requestor received AnnounceOTAProvider
I (540658) chip[SWU]: OTA image downloaded to offset 0x1a0000
I (541348) OTAImageProcessor: Applying, Boot partition set offset:0x1a0000
I (76) boot:  1 otadata          OTA data         01 00 0000f000 00002000
I (91) boot:  3 ota_0            OTA app          00 10 00020000 00177000
I (99) boot:  4 ota_1            OTA app          00 11 001a0000 00177000
I (645) cpu_start: Compile time:     Oct 15 2022 07:35:31
I (76) boot:  1 otadata          OTA data         01 00 0000f000 00002000
I (91) boot:  3 ota_0            OTA app          00 10 00020000 00177000
I (99) boot:  4 ota_1            OTA app          00 11 001a0000 00177000
I (645) cpu_start: Compile time:     Oct 15 2022 07:35:31

初始执行后,您可以重复创建和上传 OTA 映像部分中的步骤,而无需上传新映像。这次,将版本设置回 1

运行 menuconfig,然后在交互式菜单选项中执行以下操作:

  1. Component config -->

  2. CHIP Device Layer --->

  3. Device Identification Options

  4. Version String 设为 v1.0

  5. Device Software Version Number 设为 1

  6. s 保存配置,然后按 q 退出 menuconfig

在“GHA”中从住宅中移除此设备。

构建映像(如果尚未构建):

idf.py build

刷写程序:

idf.py -p /dev/ttyUSB0 erase_flash
idf.py -p /dev/ttyUSB0 flash

根据需要重复提交到 Google Home 并观察 OTA 中的步骤。

验证 OTA 软件更新

可以使用 Google Home 应用 (GHA) 查看设备软件版本。设备完成调试后,请遵循以下流程:

  1. 长按“GHA”主屏幕上的设备图块
  2. 点按右上角的 图标
  3. 点按技术信息
  4. 检查软件版本字段

显示软件版本字段的 Google Home 应用屏幕