一、概述
1、官方资料
空中升级 (OTA)
ESP HTTPS OTA
分区表
SPI Flash API
2、HTTP OTA 工作流程
3、OTA 升级方式
esp-idf
有两种方式可以通过空中(ota)升级:
- 使用
app _ update
组件提供的本地 api (原生API)。 - 使用
esp https_ota
component 提供的 简化 API ,它在本地 ota api 上添加了一个抽象层,以便使用 https protocols 进行升级。 - 有关分区表的详细信息,请参阅分区表。
- 在第一次启动时,bootloader 将加载工厂应用程序映像(即示例映像) ,然后触发 ota 升级。它将从 https 服务器下载一个新的映像,并将其保存到
ota _ 0
分区。它将自动更新ota_data
分区,以指出哪个应用程序应该从下一个重置启动。Bootloader 将读取 ota_data 分区中的内容并运行选定的应用程序。 - 这两种方法在 ota 演示中分别在
native_ota_example
和simple_ota_example
下演示。
OTA data
:OTA数据,决定使用哪个区域的固件。
Factory App
:出厂固件。
OTA_0、OTA_1
:升级的固件存储位置,升级的目标固件在 OTA_0、OTA_1 两个分区之间交互烧录。
4、OTA 示例
示例在/esp-idf/examples/system/ota
(OTA示例):
.
├── advanced_https_ota
├── native_ota_example
├── otatool
├── ota_workflow.png
├── README.md
└── simple_ota_example
native_ota_example
示例基于 app _ update
组件提供的本地 api。
simple_ota_example
示例基于 esp https_ota
组件提供的简化 api。它在本地 ota api 上添加了一个抽象层,以便使用 https protocols 进行升级。
otatool
示例演示了 ota 工具 otatool.py 允许用户执行的常见操作: 读取、写入和擦除 ota 分区,切换引导分区,切换到工厂分区。
5、API函数
API函数 | 描述 |
---|---|
esp_ota_begin | 开始写入指定分区的 OTA 更新,指定的分区被擦除到指定的图像大小。 |
esp_ota_write | 将 OTA 更新数据写入分区。数据按顺序写入分区。 |
esp_ota_write_with_offset | 将 OTA 更新数据写入分区。可以以非连续方式写入数据。 |
esp_ota_end | 完成 OTA 更新并验证新编写的应用映像。 |
esp_ota_abort | 中止 OTA 更新,释放与之关联的句柄和内存。 |
esp_ota_set_boot_partition | 为新的引导分区配置 OTA 数据。 |
esp_ota_get_boot_partition | 获取当前配置的启动应用程序的分区信息。 |
esp_ota_get_running_partition | 获取当前运行的应用程序的分区信息。 |
esp_ota_get_next_update_partition | 返回下一个应使用新固件写入的 OTA 应用程序分区。 |
esp_ota_get_partition_description | 返回应用分区的 esp_app_desc 结构。此结构包括应用程序版本。 |
esp_ota_mark_app_valid_cancel_rollback | 调用此函数以指示正在运行的应用程序运行良好。 |
esp_ota_mark_app_invalid_rollback_and_reboot | 调用此函数以通过重启回滚到以前可用的应用程序。 |
esp_ota_get_last_invalid_partition | 返回最后一个状态无效的分区(ESP_OTA_IMG_INVALID 或 ESP_OTA_IMG_ABORTED) |
esp_ota_get_state_partition | 返回给定分区的状态。 |
esp_ota_erase_last_boot_app_partition | 擦除以前的启动应用程序分区和此分区的相应 otadata 选择。 |
esp_ota_check_rollback_is_possible | 检查可以在回滚的情况下启动的插槽上的应用程序。 |
二、配置
make menuconfig
1、分区表类型配置:
Partition Table --->
Partition Table (Factory app, two OTA definitions) --->
( ) Single factory app, no OTA
(X) Factory app, two OTA definitions
( ) Custom partition table CSV
Single factory app, no OTA
选项的默认分区表信息:# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, factory, app, factory, 0x10000, 1M,
Factory app, two OTA definitions
选项的默认分区表信息:# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x4000, otadata, data, ota, 0xd000, 0x2000, phy_init, data, phy, 0xf000, 0x1000, factory, app, factory, 0x10000, 1M, ota_0, app, ota_0, 0x110000, 1M, ota_1, app, ota_1, 0x210000, 1M,
Custom partition table CSV
自定义分区信息示例:# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x4000 otadata, data, ota, 0xd000, 0x2000 phy_init, data, phy, 0xf000, 0x1000 factory, app, factory, 0x10000, 1M ota_0, app, ota_0, , 1M ota_1, app, ota_1, , 1M nvs_key, data, nvs_keys, , 0x1000
2、固件升级(HTTP/HTTPS服务器)配置:
注意配置的 URL 为 http
还是 https
服务器。
Example Configuration --->
(http://192.168.0.107:8070/hello-world.bin) Firmware Upgrade URL
[ ] Skip server certificate CN fieldcheck
[ ] Skip firmware version check
(4) Number of the GPIO input for diagnostic
(5000) OTA Receive Timeout
- 固件升级URL
Skip server certificate CN fieldcheck
:跳过服务器证书 CN 字段检查Skip firmware version check
:跳过固件版本检查- 用于诊断的 gpio 输入
- OTA接收超时时间
Component config --->
ESP HTTPS OTA --->
[ ] Allow HTTP for OTA (WARNING: ONLY FOR TESTING PURPOSE, READ HELP)
该选项允许使用 HTTP
升级,即不需要服务器证书验证。
3、网络(WIFI)连接配置:
Example Connection Configuration --->
[*] connect using WiFi interface
(CMCC) WiFi SSID
(123456) WiFi Password
[ ] connect using Ethernet interface
[*] Obtain IPv6 address
Preferred IPv6 Type (Local Link Address) --->
- 使用WIFI接口连接(STA模式)
- 要连接的WiFi 名称
- 要连接的WiFi 密码
- 使用以太网接口连接
- 获取 ipv6地址
4、版本号配置:
Application manager --->
[*] Use time/date stamp for app
[ ] Exclude PROJECT_VER from firmware image
[ ] Exclude PROJECT_NAME from firmware image
[*] Get the project version from Kconfig
(1) Project version (NEW)
(16) The length of APP ELF SHA is stored in RAM(chars)
- 应用程序使用时间/日期戳
- 固件镜像中不包括
PROJECT_VER
- 固件镜像中不包括
PROJECT_NAME
- 从
Kconfig
获取项目版本 APP ELF SHA
的长度存储在RAM(chars)
中
三、开启HTTP/HTTPS服务器
使用 HFS 软件。
把 hello-world.bin
固件拖进服务器。
四、 测试
1、远程升级成功:
I (3972) native_ota_example: Starting OTA example
I (3972) native_ota_example: Running partition type 0 subtype 0 (offset 0x00010000)
I (4112) native_ota_example: Writing to partition subtype 16 at offset 0x110000
I (4112) native_ota_example: New firmware version: 1
I (4112) native_ota_example: Running firmware version: 1
I (5312) native_ota_example: esp_ota_begin succeeded
I (6122) native_ota_example: Connection closed
I (6122) native_ota_example: Total Write binary data length: 151616
I (6122) esp_image: segment 0: paddr=0x00110020 vaddr=0x3f400020 size=0x06100 ( 24832) map
I (6142) esp_image: segment 1: paddr=0x00116128 vaddr=0x3ffb0000 size=0x02008 ( 8200)
I (6152) esp_image: segment 2: paddr=0x00118138 vaddr=0x40080000 size=0x00400 ( 1024)
0x40080000: _WindowOverflow4 at /home/pjw/ESP32/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730
I (6152) esp_image: segment 3: paddr=0x00118540 vaddr=0x40080400 size=0x07ad8 ( 31448)
I (6172) esp_image: segment 4: paddr=0x00120020 vaddr=0x400d0020 size=0x13058 ( 77912) map
0x400d0020: _stext at ??:?
I (6202) esp_image: segment 5: paddr=0x00133080 vaddr=0x40087ed8 size=0x01f90 ( 8080)
0x40087ed8: xTaskGetTickCountFromISR at /home/pjw/ESP32/esp-idf/components/freertos/tasks.c:2313
I (6212) esp_image: segment 0: paddr=0x00110020 vaddr=0x3f400020 size=0x06100 ( 24832) map
I (6222) esp_image: segment 1: paddr=0x00116128 vaddr=0x3ffb0000 size=0x02008 ( 8200)
I (6222) esp_image: segment 2: paddr=0x00118138 vaddr=0x40080000 size=0x00400 ( 1024)
0x40080000: _WindowOverflow4 at /home/pjw/ESP32/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730
I (6232) esp_image: segment 3: paddr=0x00118540 vaddr=0x40080400 size=0x07ad8 ( 31448)
I (6242) esp_image: segment 4: paddr=0x00120020 vaddr=0x400d0020 size=0x13058 ( 77912) map
0x400d0020: _stext at ??:?
I (6272) esp_image: segment 5: paddr=0x00133080 vaddr=0x40087ed8 size=0x01f90 ( 8080)
0x40087ed8: xTaskGetTickCountFromISR at /home/pjw/ESP32/esp-idf/components/freertos/tasks.c:2313
I (6332) native_ota_example: Prepare to restart system!
I (6332) wifi:state: run -> init (0)
I (6332) wifi:pm stop, total sleep time: 606988 us / 3535425 us
I (6332) wifi:new:<6,0>, old:<6,2>, ap:<255,255>, sta:<6,2>, prof:1
W (6342) wifi:hmac tx: stop, discard
W (6342) wifi:hmac tx: stop, discard
I (6382) wifi:flush txq
I (6382) wifi:stop sw txq
I (6382) wifi:lmac stop hw txq
I (6382) wifi:Deinit lldesc rx mblock:10
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:6936
load:0x40078000,len:13852
load:0x40080400,len:4548
entry 0x400806ec
2、远程升级失败:
报错:
I (3972) native_ota_example: Starting OTA example
I (3972) native_ota_example: Running partition type 0 subtype 0 (offset 0x00010000)
E (4172) esp-tls: Failed to connnect to host (errno 104)
E (4172) esp-tls: Failed to open new connection
E (4172) TRANS_SSL: Failed to open a new connection
E (4172) HTTP_CLIENT: Connection failed, sock < 0
E (4182) native_ota_example: Failed to open HTTP connection: ESP_ERR_HTTP_CONNECT
E (4192) native_ota_example: Exiting task due to fatal error...
解决:
HTTP未开启,开一个HTTP服务器,可以使用 HFS
软件。
报错:
I (3972) native_ota_example: Starting OTA example
I (3972) native_ota_example: Running partition type 0 subtype 0 (offset 0x00010000)
E (4112) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x7280
I (4112) esp-tls-mbedtls: Certificate verified.
E (4112) esp-tls: Failed to open new connection
E (4122) TRANS_SSL: Failed to open a new connection
E (4132) HTTP_CLIENT: Connection failed, sock < 0
E (4132) native_ota_example: Failed to open HTTP connection: ESP_ERR_HTTP_CONNECT
E (4142) native_ota_example: Exiting task due to fatal error...
解决:
配置的 URL 为 https
服务器,但是开的是 http
服务器。所以无法验证报错。
报错:
调用esp_ota_end
函数报错:
E (411628) esp_image: invalid segment length 0xd041a3a0
E (411628) ota: Image validation failed, image is corrupted
E (411628) ota: esp_ota_end failed (ESP_ERR_OTA_VALIDATE_FAILED)!
E (182367) esp_image: invalid segment length 0xffffffff
E (182377) ota: Image validation failed, image is corrupted
E (182377) ota: esp_ota_end failed (ESP_ERR_OTA_VALIDATE_FAILED)!
解决:
ESP_ERR_OTA_VALIDATE_FAILED
:如果 OTA 应用程序图像无效,则会出错
校验长度失败,或者固件包不完整就会报错。
注意app_ota_write
函数是按顺序写入的,要校验接收的固件包序号,是否是重发包。
报错:
调用esp_ota_set_boot_partition
函数报错:
E (755578) esp_image: invalid segment length 0xd041a3a0
E (755578) ota: esp_ota_set_boot_partition failed (ESP_ERR_OTA_VALIDATE_FAILED)!