目录
一、什么是OTA
OTA(Over-The-Air,空中升级)是指通过无线网络(如Wi-Fi、蓝牙、蜂窝网络等)远程更新设备固件的技术,无需物理连接(如USB/UART烧录)。它广泛应用于物联网(IoT)设备,如智能家居、可穿戴设备、工业传感器等,以实现远程修复漏洞、功能升级或优化性能。
二、ESP32的OTA功能
ESP32(及ESP-IDF开发框架)提供了完整的OTA解决方案,支持安全、可靠的固件更新。以下是核心功能介绍:
1. OTA升级方式
ESP32支持多种OTA方式:
方式 | 描述 |
---|---|
HTTP(S) OTA | 从Web服务器下载固件(如Nginx、AWS S3),适合云端管理的大规模设备升级。 |
MQTT OTA | 通过MQTT协议接收固件(需自定义协议),适合低带宽或私有物联网平台。 |
蓝牙OTA | 通过BLE传输固件,适用于无Wi-Fi环境的设备(如穿戴设备)。 |
本地串口OTA | 通过UART串口传输固件(类似esptool.py ,但由设备自身控制)。 |
2. OTA升级流程
1)分区表设计
ESP32的Flash被划分为多个分区,OTA升级依赖以下关键分区:
# Name, Type, SubType, Offset, Size, Flags # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap nvs, data, nvs, , 0x4000, otadata, data, ota, , 0x2000, phy_init, data, phy, , 0x1000, factory, app, factory, , 1M, ota_0, app, ota_0, , 1M, ota_1, app, ota_1, , 1M,
-
factory
:出厂固件(初始备份)。 -
ota_0
/ota_1
:OTA应用分区(双分区交替使用,确保回滚安全)。 -
otadata
:记录当前活跃的OTA分区(如ota_0
或ota_1
)。 -
nvs
:存储Wi-Fi配置、设备密钥等非易失性数据。
2)固件下载与验证
- 设备从服务器下载固件,并校验SHA-256哈希值(防篡改)。
- 写入非活跃的OTA分区(如当前运行
ota_0
,则写入ota_1
)。
3)分区切换
通过esp_ota_set_boot_partition()
更新otadata
,标记新分区为下次启动目标。
4)安全回滚
- 若新固件启动失败,ESP32可自动回滚到旧版本(需启用
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
)。 - 需在代码中调用
esp_ota_mark_app_valid_cancel_rollback()
确认固件有效。
3. 关键API函数
函数 | 作用 |
---|---|
esp_ota_begin() | 初始化OTA升级会话 |
esp_ota_write() | 写入固件数据块 |
esp_ota_end() | 结束OTA升级并验证固件 |
esp_ota_set_boot_partition() | 设置下次启动的分区 |
esp_ota_get_running_partition() | 获取当前运行的分区 |
4. 安全机制
- 签名验证:使用RSA或ECDSA签名确保固件来源可信(需启用
CONFIG_SECURE_BOOT
)。 - 加密传输:通过HTTPS或MQTT over TLS保护固件传输。
- 防回滚攻击:版本号检查(
esp_ota_check_rollback_is_possible()
)。
5. 实战示例(HTTP OTA)
使用以下命令的前提是,已经按照如下教程搭建好了ubuntu编译+esp-idf的开发环境:ESP32入门——开发环境搭建_esp32开发环境搭建-CSDN博客
示例重点内容:
复制esp-idf中的hello_world示例,编译后得到hello_world.bin作为待升级固件
下载HFS,将hello_world.bin拖动到HFS中,为ota升级提供HTTP支持
复制esp-idf中的simple_ota_example示例,进行ota功能演示
电脑与esp32需要在同一局域网下,目的是为了让esp32能够顺利访问到电脑的HTTP服务(为了实现这个条件,我让这两者都连接到名为nola的wifi)
1)复制esp-idf中的hello_world示例,编译后得到在build文件夹下得到hello_world.bin
cd ~
cd ./esp32
cp -r ./esp-idf/examples/get-started/hello_world/ ./hello_world
cd ./hello_world
idf.py build
2)下载HFS,将hello_world.bin拖动到HFS中,记住HTTP的URL:http://10.8.20.164/hello_world.bin
3)复制esp-idf中的simple_ota_example示例,进行ota功能演示(我使用的开发板是ESP-WROOM-32)
cd ~
cd ./esp32
cp -r ./esp-idf/examples/system/ota/simple_ota_example/ ./simple_ota_example
cd ./simple_ota_example
运行idf.py menuconfig,进行如下配置:
1)Example Configuration → firmware upgrade url endpoint (string),填入http://10.8.20.164/hello_world.bin
2)选中Example Configuration → Skip server certificate CN fieldcheck
3)取消Example Configuration → Support firmware upgrade bind specified interface
4)Example Connection Configuration → WiFi SSID,填入nola
5)Example Connection Configuration → WiFi Password,填入11111111
6)选中Component config → ESP HTTPS OTA → Allow HTTP for OTA (WARNING: ONLY FOR TESTING PURPOSE, READ HELP)
7)取消Component config → mbedTLS → Certificate Bundle → Enable trusted root certificate bundle
编译烧录:
idf.py build
idf.py flash monitor
烧录成功后可以在终端看到ESP32在ota成功后,自动重启并运行了hello_world固件
6. 常见问题
-
Q:OTA后仍从
factory
启动?
→ 检查otadata
分区是否损坏,或未调用esp_ota_set_boot_partition()
。 -
Q:Wi-Fi连接失败?
→ OTA后需重新初始化NVS(nvs_flash_erase()
+nvs_flash_init()
)。 -
Q:升级中途断电怎么办?
→ 双分区设计确保旧固件完整,下次启动自动回退。