ESP32 各型号远程 OTA 实战教程
ESP32 各型号远程 OTA 实战教程
1. 教程目标
本教程介绍 ESP32 系列芯片如何实现远程 OTA 升级。
OTA 的全称是 Over-The-Air Update,也就是设备不需要再次连接 USB 数据线,而是通过网络下载新的固件,并自动完成升级。
本教程主要覆盖以下型号:
| 型号 | 是否适合直接 WiFi OTA | 推荐 OTA 方式 |
|---|---|---|
| ESP32 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-S2 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-S3 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-C2 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-C3 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-C5 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-C6 | 适合 | WiFi HTTP / HTTPS OTA |
| ESP32-H2 | 不适合直接 WiFi OTA | BLE / Zigbee / Thread 网关 OTA |
| ESP32-P4 | 本体不适合直接 WiFi OTA | 外接 ESP32-C6 / ESP32-C5 / 以太网模块 OTA |
普通 ESP32、ESP32-S2、ESP32-S3、ESP32-C3、ESP32-C6 等带 WiFi 的芯片,可以直接通过 WiFi 下载固件完成远程 OTA。
ESP32-H2 没有 WiFi,主要面向 Bluetooth LE 和 IEEE 802.15.4 场景,因此不能直接套用 WiFi HTTP OTA。
ESP32-P4 本体没有集成无线连接能力,如果要做远程 OTA,一般需要外接无线模块、以太网模块,或者通过其他联网芯片协助完成升级。
2. OTA 的基本原理
ESP32 的 OTA 升级不是直接覆盖当前正在运行的程序,而是采用双分区机制。
常见流程如下:
当前程序运行在 ota_0 分区
新固件下载到 ota_1 分区
写入成功后修改启动标记
设备重启
Bootloader 从 ota_1 启动新固件
下一次升级时再写回 ota_0
因此,ESP32 要支持 OTA,分区表中必须有 OTA 相关分区。
最基本需要:
otadata
ota_0
ota_1
各分区作用如下:
| 分区 | 作用 |
|---|---|
| nvs | 保存 WiFi、配置参数等非易失性数据 |
| otadata | 保存当前应该从哪个 OTA 分区启动 |
| ota_0 | 第一个应用程序分区 |
| ota_1 | 第二个应用程序分区 |
| phy_init | 保存射频初始化相关数据 |
| spiffs / littlefs | 可选,用于保存文件资源 |
如果分区表中没有 ota_0 和 ota_1,设备就无法实现标准双分区 OTA。
3. 推荐硬件选择
3.1 入门学习推荐
如果只是学习远程 OTA,推荐选择:
ESP32 DevKit
ESP32-C3 开发板
ESP32-S3 开发板
原因:
资料多
价格低
WiFi 支持完整
Arduino 和 ESP-IDF 都容易上手
3.2 正式项目推荐
如果是正式项目,推荐选择:
ESP32-S3 N8R8
ESP32-S3 N16R8
ESP32-C6
原因:
Flash 空间更大
固件不容易超过 OTA 分区大小
后期可以加入 HTTPS、MQTT、Web 配网、日志、屏幕、传感器等功能
3.3 不建议新手直接选择的型号
不建议新手一开始就选择:
ESP32-H2
ESP32-P4
原因:
ESP32-H2 没有 WiFi,不能直接使用 WiFi HTTP OTA
ESP32-P4 本体没有无线连接能力,通常需要外接联网模块
如果只是想做普通远程升级,建议先使用 ESP32、ESP32-C3、ESP32-S3 或 ESP32-C6。
4. 远程 OTA 整体流程
一个完整的远程 OTA 流程如下:
1. 第一次通过 USB 烧录基础固件
2. 基础固件中写入 WiFi 连接逻辑和 OTA 逻辑
3. 服务器上放置 version.json 和 firmware.bin
4. ESP32 启动后请求 version.json
5. 判断服务器版本是否高于本地版本
6. 如果有新版本,就下载 firmware.bin
7. 将新固件写入另一个 OTA 分区
8. 写入成功后重启
9. 新固件启动
10. 如果开启回滚机制,新固件需要确认自身运行正常
5. 服务器文件准备
服务器上建议放两个文件:
version.json
firmware.bin
目录示例:
ota-server/
├── version.json
└── firmware.bin
6. version.json 示例
version.json 用于告诉 ESP32 当前服务器上的最新版本和固件下载地址。
示例:
{
"version": "1.0.1",
"url": "http://你的服务器地址/firmware.bin",
"description": "修复已知问题,优化联网稳定性"
}
字段说明:
| 字段 | 作用 |
|---|---|
| version | 服务器上的最新固件版本号 |
| url | 固件 bin 文件下载地址 |
| description | 更新说明,可选 |
7. 固件 bin 文件说明
firmware.bin 是编译出来的应用程序固件。
注意,它不是下面这些文件:
不是 bootloader.bin
不是 partitions.bin
不是 merged.bin
不是 ota_data_initial.bin
真正用于 OTA 的是应用程序 app bin 文件。
在 Arduino IDE 中,一般是:
项目名.ino.bin
在 ESP-IDF 中,一般是:
build/项目名.bin
8. 本地测试服务器搭建
如果只是测试,可以在电脑上用 Python 快速启动一个 HTTP 服务器。
先创建一个目录:
mkdir ota-server
cd ota-server
把下面两个文件放进去:
version.json
firmware.bin
然后启动服务器:
python -m http.server 8000
如果电脑 IP 是:
192.168.1.100
那么 ESP32 访问地址就是:
http://192.168.1.100:8000/version.json
http://192.168.1.100:8000/firmware.bin
注意:
ESP32 和电脑必须连接到同一个局域网
电脑防火墙不能拦截 8000 端口
firmware.bin 必须能通过浏览器直接下载
可以先在浏览器中打开:
http://192.168.1.100:8000/version.json
如果浏览器能看到 JSON 内容,说明服务器基本正常。
再打开:
http://192.168.1.100:8000/firmware.bin
如果浏览器能下载 bin 文件,说明固件直链正常。
9. Arduino 方式实现远程 OTA
Arduino 方式适合快速入门。
适合型号:
ESP32
ESP32-S2
ESP32-S3
ESP32-C2
ESP32-C3
ESP32-C5
ESP32-C6
不适合直接套用:
ESP32-H2
ESP32-P4
10. Arduino IDE 分区选择
打开 Arduino IDE:
工具 -> Partition Scheme
选择带 OTA 的分区,例如:
Default OTA
Minimal SPIFFS
Huge APP with OTA
不要选择:
No OTA
Huge APP No OTA
如果选择了不带 OTA 的分区,Update.begin() 很可能会失败。
11. Arduino 依赖库
Arduino 示例代码使用 ESP32 Arduino Core 自带库:
#include <WiFi.h>
#include <HTTPClient.h>
#include <Update.h>
不需要额外安装第三方 OTA 库。
12. Arduino 远程 OTA 完整代码
下面代码实现:
1. 连接 WiFi
2. 请求 version.json
3. 判断版本号
4. 下载 firmware.bin
5. 写入 OTA 分区
6. 升级成功后自动重启
代码如下:
#include <WiFi.h>
#include <HTTPClient.h>
#include <Update.h>
const char* WIFI_SSID = "你的WiFi名称";
const char* WIFI_PASSWORD = "你的WiFi密码";
const char* CURRENT_VERSION = "1.0.0";
const char* VERSION_URL = "http://192.168.1.100:8000/version.json";
String parseValue(String json, String key) {
String target = "\"" + key + "\"";
int keyIndex = json.indexOf(target);
if (keyIndex < 0) return "";
int colonIndex = json.indexOf(":", keyIndex);
if (colonIndex < 0) return "";
int firstQuote = json.indexOf("\"", colonIndex + 1);
if (firstQuote < 0) return "";
int secondQuote = json.indexOf("\"", firstQuote + 1);
if (secondQuote < 0) return "";
return json.substring(firstQuote + 1, secondQuote);
}
int compareVersion(String serverVersion, String currentVersion) {
serverVersion.trim();
currentVersion.trim();
if (serverVersion == currentVersion) {
return 0;
}
int s1 = 0, s2 = 0, s3 = 0;
int c1 = 0, c2 = 0, c3 = 0;
sscanf(serverVersion.c_str(), "%d.%d.%d", &s1, &s2, &s3);
sscanf(currentVersion.c_str(), "%d.%d.%d", &c1, &c2, &c3);
if (s1 != c1) return s1 > c1 ? 1 : -1;
if (s2 != c2) return s2 > c2 ? 1 : -1;
if (s3 != c3) return s3 > c3 ? 1 : -1;
return 0;
}
bool downloadAndUpdate(String firmwareUrl) {
Serial.println("开始 OTA 下载");
Serial.println(firmwareUrl);
WiFiClient client;
HTTPClient http;
http.begin(client, firmwareUrl);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) {
Serial.printf("固件请求失败,HTTP 状态码: %d\n", httpCode);
http.end();
return false;
}
int contentLength = http.getSize();
if (contentLength <= 0) {
Serial.println("固件大小异常");
http.end();
return false;
}
Serial.printf("固件大小: %d bytes\n", contentLength);
bool canBegin = Update.begin(contentLength);
if (!canBegin) {
Serial.println("OTA 分区空间不足,无法开始升级");
http.end();
return false;
}
WiFiClient* stream = http.getStreamPtr();
size_t written = Update.writeStream(*stream);
Serial.printf("已写入: %d bytes\n", written);
if (written != contentLength) {
Serial.println("写入大小和固件大小不一致");
Update.abort();
http.end();
return false;
}
if (!Update.end()) {
Serial.printf("OTA 结束失败,错误码: %d\n", Update.getError());
http.end();
return false;
}
if (!Update.isFinished()) {
Serial.println("OTA 未完整完成");
http.end();
return false;
}
Serial.println("OTA 成功,准备重启");
http.end();
delay(1000);
ESP.restart();
return true;
}
void checkUpdate() {
Serial.println("检查远程版本");
WiFiClient client;
HTTPClient http;
http.begin(client, VERSION_URL);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) {
Serial.printf("版本文件请求失败,HTTP 状态码: %d\n", httpCode);
http.end();
return;
}
String payload = http.getString();
http.end();
Serial.println("服务器返回:");
Serial.println(payload);
String serverVersion = parseValue(payload, "version");
String firmwareUrl = parseValue(payload, "url");
if (serverVersion.length() == 0 || firmwareUrl.length() == 0) {
Serial.println("version.json 格式错误");
return;
}
Serial.print("当前版本: ");
Serial.println(CURRENT_VERSION);
Serial.print("服务器版本: ");
Serial.println(serverVersion);
if (compareVersion(serverVersion, CURRENT_VERSION) > 0) {
Serial.println("发现新版本,开始升级");
downloadAndUpdate(firmwareUrl);
} else {
Serial.println("当前已经是最新版本");
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println("ESP32 远程 OTA 示例启动");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("正在连接 WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi 已连接,IP: ");
Serial.println(WiFi.localIP());
checkUpdate();
}
void loop() {
}
13. 第一次烧录
第一次必须通过 USB 烧录,因为设备还没有 OTA 功能。
烧录后打开串口监视器:
波特率:115200
正常输出类似:
ESP32 远程 OTA 示例启动
正在连接 WiFi...
WiFi 已连接,IP: 192.168.1.120
检查远程版本
当前版本: 1.0.0
服务器版本: 1.0.1
发现新版本,开始升级
OTA 成功,准备重启
14. 第二次升级测试
先修改代码中的版本号:
const char* CURRENT_VERSION = "1.0.1";
然后重新编译并导出 bin 文件。
在 Arduino IDE 中可以通过:
项目 -> 导出已编译的二进制文件
找到生成的 bin 文件后,将它重命名为:
firmware.bin
然后替换服务器目录中的旧固件。
同时修改服务器上的 version.json:
{
"version": "1.0.1",
"url": "http://192.168.1.100:8000/firmware.bin",
"description": "升级到 1.0.1"
}
重启 ESP32 后,设备会检测到服务器版本更高,然后自动下载新固件并升级。
15. Arduino HTTPS OTA 改法
HTTP 适合测试,正式项目建议使用 HTTPS。
如果使用 HTTPS 地址:
https://example.com/firmware.bin
需要引入:
#include <WiFiClientSecure.h>
并把:
WiFiClient client;
改成:
WiFiClientSecure client;
client.setInsecure();
示例:
#include <WiFiClientSecure.h>
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
http.begin(client, firmwareUrl);
注意:
client.setInsecure() 只适合测试
正式产品不建议关闭证书校验
正式项目应配置服务器 CA 根证书
16. ESP-IDF 方式实现远程 OTA
ESP-IDF 更适合正式项目。
适合场景:
工业设备
机器人
网关
长期运行设备
需要 HTTPS 证书校验
需要 OTA 回滚
需要日志和错误码
17. ESP-IDF 创建项目
创建项目:
idf.py create-project esp32_ota_demo
cd esp32_ota_demo
如果你已经有项目,可以直接在原项目中加入 OTA 代码。
18. ESP-IDF 设置目标芯片
根据自己的芯片设置 target。
ESP32:
idf.py set-target esp32
ESP32-S2:
idf.py set-target esp32s2
ESP32-S3:
idf.py set-target esp32s3
ESP32-C3:
idf.py set-target esp32c3
ESP32-C6:
idf.py set-target esp32c6
ESP32-H2:
idf.py set-target esp32h2
ESP32-P4:
idf.py set-target esp32p4
注意:
ESP32-H2 没有 WiFi,不能直接使用 WiFi HTTP OTA 示例
ESP32-P4 本体没有无线连接,需要外接联网方案
19. ESP-IDF 配置 OTA 分区
进入配置:
idf.py menuconfig
选择:
Partition Table
然后选择:
Factory app, two OTA definitions
这样会生成类似结构:
factory
ota_0
ota_1
otadata
如果固件比较大,可以使用自定义分区表。
20. 4MB Flash 推荐分区表
文件名:
partitions.csv
内容:
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x4000
otadata, data, ota, 0xd000, 0x2000
phy_init, data, phy, 0xf000, 0x1000
ota_0, app, ota_0, 0x10000, 1900K
ota_1, app, ota_1, , 1900K
说明:
去掉 factory 分区后,ota_0 和 ota_1 可以更大
适合固件体积比较大的项目
21. 8MB Flash 推荐分区表
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x6000
otadata, data, ota, 0xf000, 0x2000
phy_init, data, phy, 0x11000, 0x1000
ota_0, app, ota_0, 0x20000, 3M
ota_1, app, ota_1, , 3M
storage, data, spiffs, , 1M
适合:
ESP32-S3 N8
ESP32-S3 N16
固件较大的 UI 项目
带 WebServer 的项目
带 MQTT、HTTPS、JSON 的项目
22. ESP-IDF HTTPS OTA 核心代码
文件:
main/main.c
示例:
#include <stdio.h>
#include "esp_log.h"
#include "esp_system.h"
#include "esp_https_ota.h"
#include "esp_http_client.h"
static const char *TAG = "OTA_DEMO";
extern const uint8_t server_cert_pem_start[] asm("_binary_server_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_server_cert_pem_end");
void start_https_ota(void)
{
ESP_LOGI(TAG, "开始 HTTPS OTA");
esp_http_client_config_t http_config = {
.url = "https://example.com/firmware.bin",
.cert_pem = (const char *)server_cert_pem_start,
.timeout_ms = 10000,
};
esp_https_ota_config_t ota_config = {
.http_config = &http_config,
};
esp_err_t ret = esp_https_ota(&ota_config);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "OTA 成功,准备重启");
esp_restart();
} else {
ESP_LOGE(TAG, "OTA 失败,错误码: %s", esp_err_to_name(ret));
}
}
23. ESP-IDF 添加证书文件
如果使用 HTTPS,需要把服务器 CA 证书放到项目中。
目录示例:
main/
├── main.c
├── CMakeLists.txt
└── server_cert.pem
main/CMakeLists.txt 示例:
idf_component_register(
SRCS "main.c"
INCLUDE_DIRS "."
EMBED_TXTFILES server_cert.pem
)
然后在代码中通过:
extern const uint8_t server_cert_pem_start[] asm("_binary_server_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_server_cert_pem_end");
引用证书内容。
24. ESP-IDF 编译和烧录
编译:
idf.py build
烧录:
idf.py flash
打开串口监视器:
idf.py monitor
编译出的 app 固件一般位于:
build/项目名.bin
把这个 bin 文件上传到服务器,作为 OTA 固件即可。
25. OTA 回滚机制说明
正式项目建议加入 OTA 回滚。
OTA 回滚的作用是:
如果新固件启动后崩溃
或者新固件没有主动确认运行正常
Bootloader 可以回退到上一个可用固件
典型流程:
1. 设备下载新固件
2. 重启进入新固件
3. 新固件启动后先执行自检
4. WiFi 正常
5. 关键任务正常
6. 关键外设正常
7. 调用确认函数,标记新固件有效
8. 如果没有确认,下次启动可以回滚
ESP-IDF 中常见确认方式:
esp_ota_mark_app_valid_cancel_rollback();
如果检测失败,可以标记当前固件无效并重启:
esp_ota_mark_app_invalid_rollback_and_reboot();
建议在新固件启动后做这些检查:
WiFi 是否能连接
NVS 配置是否能读取
主任务是否正常创建
传感器是否初始化成功
服务器是否能访问
关键业务逻辑是否正常
26. 各型号实战建议
26.1 ESP32
推荐方案:
Arduino HTTP OTA 入门
ESP-IDF HTTPS OTA 正式项目
特点:
资料最多
兼容性最好
适合新手学习
适合项目:
传感器节点
小车控制器
MQTT 设备
普通 IoT 终端
26.2 ESP32-S2
推荐方案:
WiFi HTTP / HTTPS OTA
特点:
单核
有 WiFi
没有传统蓝牙
支持 USB OTG
注意:
代码基本和 ESP32 一样
但 Arduino 选板必须选 ESP32-S2 对应开发板
26.3 ESP32-S3
推荐方案:
ESP-IDF HTTPS OTA
Arduino HTTP OTA 也可以
特点:
性能较强
常见开发板带 PSRAM
适合屏幕、摄像头、AI、语音项目
建议:
尽量选择 8MB 或 16MB Flash 版本
不要使用太小的 OTA 分区
常见型号:
ESP32-S3 N8R8
ESP32-S3 N16R8
26.4 ESP32-C3
推荐方案:
Arduino HTTP OTA
ESP-IDF HTTPS OTA
特点:
RISC-V 单核
价格低
功耗低
适合普通联网设备
注意:
很多 ESP32-C3 模组是 4MB Flash
如果固件太大,OTA 分区可能不够
建议:
少用大型库
减少 WebServer 页面资源
减少 SPIFFS 空间
控制固件体积
26.5 ESP32-C6
推荐方案:
WiFi HTTPS OTA
特点:
支持 WiFi
支持 BLE
支持 IEEE 802.15.4
适合智能家居和 Matter 方向
注意:
如果只是普通 OTA,直接走 WiFi 即可
如果走 Zigbee / Thread,需要网关配合
26.6 ESP32-H2
推荐方案:
BLE OTA
Zigbee OTA
Thread OTA
通过网关 OTA
特点:
没有 WiFi
有 Bluetooth LE
有 IEEE 802.15.4
适合低功耗智能家居终端
不适合:
直接照搬 ESP32 的 WiFi HTTP OTA 示例
典型架构:
服务器
↓
WiFi 网关,例如 ESP32-C6
↓
Zigbee / Thread / BLE
↓
ESP32-H2 设备
26.7 ESP32-P4
推荐方案:
外接无线模块 OTA
以太网 OTA
USB / 本地升级
特点:
性能强
适合显示、HMI、视觉类项目
本体没有集成无线连接
常见架构:
服务器
↓
ESP32-C6 或 ESP32-C5 联网模块
↓
SPI / SDIO / UART
↓
ESP32-P4 主控
如果项目一定要远程 OTA,建议选择带无线协处理器的开发板,或者直接选 ESP32-S3 / ESP32-C6 作为主控。
27. 版本号设计建议
简单项目可以使用:
1.0.0
1.0.1
1.1.0
2.0.0
规则:
主版本.功能版本.修复版本
示例:
| 版本号 | 含义 |
|---|---|
| 1.0.0 | 初始版本 |
| 1.0.1 | 修复 bug |
| 1.1.0 | 增加功能 |
| 2.0.0 | 大版本重构 |
ESP32 本地代码中写:
const char* CURRENT_VERSION = "1.0.0";
服务器 version.json 写:
{
"version": "1.0.1",
"url": "http://192.168.1.100:8000/firmware.bin"
}
如果服务器版本更高,就执行 OTA。
28. 正式项目安全建议
正式项目不建议只做简单 HTTP OTA。
建议至少做到:
1. 使用 HTTPS
2. 校验证书
3. 校验固件版本
4. 校验固件大小
5. 校验固件哈希
6. 支持失败回滚
7. 服务器不允许随便上传固件
8. 固件下载地址不要公开可写
更高安全要求可以加入:
Secure Boot
Flash Encryption
固件签名校验
设备唯一 ID 鉴权
Token 鉴权
29. OTA 常见错误和解决方法
29.1 Update.begin 失败
可能原因:
没有 OTA 分区
OTA 分区太小
当前固件太大
分区表选择错误
解决方法:
选择带 OTA 的分区
减小固件体积
换更大的 Flash
自定义 partitions.csv
29.2 HTTP 请求失败
可能原因:
ESP32 没有联网
服务器地址写错
电脑防火墙拦截
ESP32 和服务器不在同一个网络
firmware.bin 不是直链
解决方法:
浏览器先测试固件地址能不能直接下载
检查 ESP32 串口输出的 IP
检查服务器 IP 是否正确
关闭或放行防火墙端口
29.3 固件下载了但无法启动
可能原因:
固件不是当前芯片型号编译的
ESP32-C3 烧了 ESP32 的固件
ESP32-S3 烧了 ESP32 的固件
分区表不一致
固件损坏
解决方法:
确认 Arduino 选板正确
确认 ESP-IDF set-target 正确
确认上传的是 app bin
确认服务器文件完整
29.4 HTTPS 失败
可能原因:
证书不正确
系统时间不正确
服务器证书链不完整
使用了自签证书
解决方法:
测试阶段可以使用 setInsecure()
正式项目配置 CA 证书
确认服务器 HTTPS 证书有效
29.5 OTA 后一直重复升级
可能原因:
CURRENT_VERSION 没有修改
服务器 version.json 一直比本地版本高
新固件版本号仍然是旧版本
解决方法:
每次发布新固件都修改 CURRENT_VERSION
服务器 version.json 和固件版本保持一致
30. 推荐开发顺序
新手建议按这个顺序做:
第一步:ESP32-C3 或 ESP32-S3 跑通 WiFi
第二步:搭建 Python HTTP Server
第三步:浏览器确认 firmware.bin 可以下载
第四步:Arduino 跑通 HTTP OTA
第五步:加入 version.json 版本判断
第六步:改成 HTTPS
第七步:迁移到 ESP-IDF
第八步:加入 OTA 回滚
第九步:加入固件签名和安全启动
不要一开始就做:
HTTPS + 证书 + 回滚 + 签名 + 加密 + 多设备管理
这样排错难度会很高。
31. 最小可运行测试方案
硬件:
ESP32-C3 开发板
或者 ESP32-S3 开发板
电脑:
Windows / Linux / macOS 都可以
安装 Python
安装 Arduino IDE
步骤:
1. Arduino IDE 选择带 OTA 的分区
2. 修改 WiFi 名称和密码
3. 修改 VERSION_URL
4. 第一次 USB 烧录
5. 导出新的 firmware.bin
6. 放到 Python HTTP Server 目录
7. 修改 version.json
8. 重启 ESP32
9. 查看串口输出
成功标志:
串口输出 OTA 成功
设备自动重启
重启后运行新版本代码
32. 总结
ESP32 远程 OTA 的核心不是某一个库,而是完整流程:
正确分区表
正确固件 bin
可靠下载地址
版本判断
写入未运行分区
重启切换
失败回滚
普通 WiFi 型 ESP32,例如 ESP32、ESP32-S2、ESP32-S3、ESP32-C3、ESP32-C6,都可以直接做 WiFi HTTP / HTTPS OTA。
ESP32-H2 没有 WiFi,适合通过 BLE、Thread、Zigbee 或网关 OTA。
ESP32-P4 本体没有集成无线连接,通常需要外接 ESP32-C6、ESP32-C5、以太网或其他联网模块实现远程 OTA。
新手最推荐:
ESP32-C3 + Arduino + HTTP OTA
正式项目推荐:
ESP32-S3 / ESP32-C6 + ESP-IDF + HTTPS OTA + 回滚机制
更多推荐
所有评论(0)