跳转到内容

ESP32 OTA 机制

ESP32 OTA 机制

本节介绍 ESP32 支持的三种 OTA 升级机制及其适用场景。学习完成后,您将能够:

  • 区分 Arduino OTA、HTTP OTA 和 HTTPS OTA 的区别
  • 评估不同 OTA 方式的安全性和适用性
  • 根据买家需求推荐合适的 OTA 方案
  • 理解各方案的实现复杂度

在开始本节之前,请确保:

  • 理解 OTA 基本概念
  • 了解 ESP32 WiFiClient / WiFiClientSecure 库
  • 了解 HTTP/HTTPS 协议基础
特性Arduino OTAHTTP OTAHTTPS OTA
传输协议Arduino 私有协议HTTPHTTPS (TLS)
安全性无加密无加密加密传输
实现复杂度⭐ 低⭐⭐ 中⭐⭐⭐ 高
服务器依赖Arduino IDEHTTP 服务器HTTPS 服务器
推荐场景开发调试局域网/可信网络生产/互联网部署
传输加密❌ 无❌ 无✅ TLS 1.2/1.3
固件签名❌ 不支持可自行实现可自行实现
批量管理❌ 不适用✅ 支持✅ 推荐

Arduino OTA 使用 Arduino 框架内建的 ArduinoOTA 库,通过 Arduino IDE 的”通过网络上传”功能直接推送固件。

#include <ArduinoOTA.h>
void setup() {
WiFi.begin(ssid, password);
// 等待 WiFi 连接
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
delay(500);
}
// 初始化 Arduino OTA
ArduinoOTA.setHostname("esp32-factory-device");
ArduinoOTA.setPassword("ota_password");
ArduinoOTA.onStart([]() {
String type = (ArduinoOTA.getCommand() == U_FLASH)
? "sketch" : "filesystem";
Serial.println("OTA 开始: " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("OTA 完成");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("进度: %u%%\n", (progress * 100) / total);
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("错误[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("认证失败");
else if (error == OTA_BEGIN_ERROR) Serial.println("开始失败");
else if (error == OTA_CONNECT_ERROR) Serial.println("连接失败");
else if (error == OTA_RECEIVE_ERROR) Serial.println("接收失败");
else if (error == OTA_END_ERROR) Serial.println("结束失败");
});
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
// 其他业务逻辑
}

特点

  • 通过 Arduino IDE 上传,适合开发阶段
  • 无需额外服务器
  • 仅适用于局域网(MDNS 发现)
  • 不支持批量部署和版本管理
场景推荐度理由
桌面开发调试✅ 推荐快速迭代,无需插拔 USB
小批量原型测试✅ 可用设备在手边时方便
已部署设备升级❌ 不推荐需要人在局域网内操作

ESP32 通过 HTTP 从远程服务器下载固件文件,写入 OTA 分区。

#include <WiFi.h>
#include <HTTPClient.h>
#include <Update.h>
const char* firmware_url = "http://192.168.1.100/firmware/esp32.bin";
void checkForUpdate() {
HTTPClient http;
http.begin(firmware_url);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
int contentLength = http.getSize();
if (contentLength > 0 && Update.begin(contentLength)) {
WiFiClient* stream = http.getStreamPtr();
size_t written = Update.writeStream(*stream);
if (written == contentLength && Update.end()) {
Serial.println("OTA 成功,准备重启");
if (Update.isFinished()) {
ESP.restart();
}
} else {
Serial.printf("OTA 失败: %s\n", Update.errorString());
}
}
} else {
Serial.printf("HTTP 请求失败: %d\n", httpCode);
}
http.end();
}

特点

  • 支持远程部署
  • 需要 HTTP 服务器(轻量级)
  • 无传输加密(明文传输)
  • 可通过 MQTT 触发升级
场景推荐度理由
局域网内升级✅ 可用内网环境风险较低
开发/测试环境✅ 推荐部署简单
生产环境互联网❌ 不推荐明文传输不安全

使用 TLS 加密的 HTTP 连接下载固件,确保传输过程中固件不被篡改和窃听。

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <Update.h>
// Let's Encrypt ISRG Root X1 证书
const char* rootCACert =
"-----BEGIN CERTIFICATE-----\n"
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n"
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n"
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n"
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n"
"h77ct384kydS5S4JgN4WZRRQ8+5RqKfD6XwMqB7X/+ABGdZ4T0vTXzSeoA8Q\n"
// ... (证书完整内容)
"-----END CERTIFICATE-----\n";
WiFiClientSecure client;
void secureOTAUpdate(const char* url) {
client.setCACert(rootCACert);
http.begin(client, url); // HTTPS URL
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
int contentLength = http.getSize();
bool canBegin = Update.begin(contentLength);
if (canBegin) {
WiFiClient* stream = http.getStreamPtr();
size_t written = Update.writeStream(*stream);
if (written == contentLength && Update.end()) {
ESP.restart();
}
}
}
}

特点

  • TLS 加密传输,防止窃听和篡改
  • 需要 HTTPS 服务器和证书
  • 证书管理增加复杂度
  • ESP32 需要存储 CA 证书(4-8KB)
场景推荐度理由
互联网远程升级✅ 必选加密传输确保安全
生产环境部署✅ 推荐行业安全最佳实践
高安全需求场景✅ 必选金融/医疗/安防
设备部署场景 ─→ 是否在局域网?
├── 是 → 是否有安全要求?
│ ├── 是 → Arduino OTA(开发)或 HTTP OTA(内网生产)
│ └── 否 → HTTP OTA(简单部署)
└── 否 → 是否在互联网上?
├── 是 → HTTPS OTA(必选)
└── 否 → 考虑其他通信方式
设备类型OTA 方式理由
开发原型Arduino OTA快速迭代,开发环境简单
内网生产设备HTTP OTA内网安全,部署简单
互联网设备(消费级)HTTPS OTA安全合规
互联网设备(工业级)HTTPS OTA + 固件签名最高安全级别
批量管理设备HTTPS OTA + 版本服务器统一版本管理
买家场景推荐 OTA 方式沟通要点
”设备在家如何升级?“HTTPS OTA”通过加密连接远程推送,安全可靠"
"新功能发布怎么更新?“HTTPS OTA + 版本服务器”云端管理版本,自动推送更新"
"开发阶段频繁改代码”Arduino OTA”IDE 直接上传,调试效率高"
"如何保证升级安全?“HTTPS OTA + 签名”加密传输 + 固件签名双重保障”

本节介绍了 ESP32 的三种 OTA 机制:

  1. Arduino OTA:开发调试专用,简单易用,仅限局域网
  2. HTTP OTA:远程升级基础,部署简单,明文传输
  3. HTTPS OTA:生产环境首选,TLS 加密传输,安全可靠

选型建议:开发用 Arduino OTA,内网用 HTTP OTA,互联网生产必须用 HTTPS OTA