ESP32-CAM OTA解决方案介绍,自动OTA更新程序的编写。
- 1、OTA技术是什么?
- 2、为何要做OTA?
- 3、ESP32-CAM OTA的方法
- 1、Basic OTA(这其实不算是OTA,因为OTA是不需要通过数据线连接pc的)
- 2、OTAWebUpload
- 3、HTTP Upload
- 4、自动OTA更新程序流程。
- 5、OTA更新的应用场景
- 6、OTA升级的好处与缺点
- 参考资料
1、OTA技术是什么?
OTA(Over-the-AirTechnology)即空中下载技术,是通过移动通信的空中接口实现对移动终端设备及SIM卡数据进行远程管理的技术。OTA升级是物联网(IOT)产品设计的一个非常重要的部分,能够实现智能设备系统漏洞修复、系统升级,通过固件和软件的升级,提供更好的服务。OTA固件升级功能不仅能够更新固件,而且还能重新配置芯片上硬件资源。同时,设备固件可通过OTA固件升级流程获得更新的补丁和更多安全算法防范病毒攻击。
以ESP32-CAM为例,我将向大家介绍如何使用ESP32-CAM进行OTA线上更新,OTA有什么用,运用场景有哪些以及流程有是什么。
2、为何要做OTA?
在解释为何要做OTA之前大家先了解一个概念,固件(Firmware):固件是指设备内部保存的设备“驱动程序”,通过固件,操作系统才能按照标准的设备驱动实现特定机器的运行动作。那么怎么更新固件呢?
固件升级,有时也称固件刷新,刷写,重写,烧录或刷机,是指把新的固件写入芯片中,代替原有的固件的过程。这就需要ESP32-CAM在自己身边,以及通过数据线连接到pc,再通过pc将固件烧录到ESP32-CAM里,这样就很麻烦。
假设你有100台ESP32-CAM,并且已经部署到使用场景中,我们怎么来更新固件。
这就是我们为何要做OTA线上更新的原因。ESP32-CAM不需要在自己身边,不需要连接pc也能进行固件的更新。效率大大增加了。
3、ESP32-CAM OTA的方法
1、Basic OTA(这其实不算是OTA,因为OTA是不需要通过数据线连接pc的)
1.将ESP32-CAM连接到ch340再通过ch340连接到pc。
2.pc编译好新的固件再将其烧录到ESP32-CAM里。
缺点:ESP32-CAM每次需要更新固件的时候都需要连接到pc。
2、OTAWebUpload
1.将ESP32-CAM连接到无线网络。
2.在pc上编译好固件。
3.查询ESP32-CAM的ip地址。
4.将查询到的ip地址在浏览器中输入。
5.最后上传编译好的固件,完成OTA固件更新。
缺点:ESP32-CAM更新固件的时候需要和pc处于同一AP下,也就是说ESP32-CAM需要在自己身边。
3、HTTP Upload
1.将ESP32-CAM连接到无线网络。
2.在PC上将要更新的固件进行build。
3.将.bin文件上传服务器。
4.ESP32自动下载。
方法三是我最近再做的项目,它的好处是ESP32-CAM不需要在身边并且更不需要连接到pc,就能实现OTA更新。
我们可以写一段代码实现当ESP32-CAM连接到AP时,检查是否存在最新的固件,如果存在则进行OTA更新,如果不存在则不进行OTA更新。
我们将这套程序称为自动OTA更新程序。
4、自动OTA更新程序流程。
提前准备:一个国际区AWS的账号,AWS网站的证书(我们通过HTTPS方式进行OTA更新所以必须要网站证书),相应的分区表(本人时候用默认分区表发现不能更新)。
流程为:将需要更新的固件编译上传AWS S3,获取AWS网站证书(通过openssl),编写一个名为version的JSON文件里面放着版本号(LV)上传S3,编写OTA更新程序在里面添加当前版本(CV),连接上AP之后程序读取S3上的名为version的JSON文件,检查是否存在最新的版本固件,如果存在则进行OTA更新,如果不存在则不进行OTA更新。
完成代码如下:
// This sketch provide the functionality of OTA Firmware Upgrade
#include <Arduino.h>
#include "time.h"
#include "WiFi.h"
#include "HttpsOTAUpdate.h"
#include "esp_ota_ops.h"
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <iostream>
#include <string>
# define LED_BUILTIN 4
String Current_version = "1.2.0";
// This sketch shows how to implement HTTPS firmware update Over The Air.
// Please provide your WiFi credentials, https URL to the firmware image and the server certificate.
static const char *ssid = "yourssid"; // your network SSID (name of wifi network)
static const char *password = "yourpassword"; // your network password
static const char *url = " "; //state url of your firmware image
static const char *endpointURL = "/version.json";
static const char *endpointHost = " ";
static const char *server_certificate = "-----BEGIN CERTIFICATE-----\n" \
"-----END CERTIFICATE-----";
static HttpsOTAStatus_t otastatus;
const int endpointPort = 443;
void HttpEvent(HttpEvent_t *event)
{
switch(event->event_id) {
case HTTP_EVENT_ERROR:
Serial.println("Http Event Error");
break;
case HTTP_EVENT_ON_CONNECTED:
Serial.println("Http Event On Connected");
break;
case HTTP_EVENT_HEADER_SENT:
Serial.println("Http Event Header Sent");
break;
case HTTP_EVENT_ON_HEADER:
Serial.printf("Http Event On Header, key=%s, value=%s\n", event->header_key, event->header_value);
break;
case HTTP_EVENT_ON_DATA:
break;
case HTTP_EVENT_ON_FINISH:
Serial.println("Http Event On Finish");
break;
case HTTP_EVENT_DISCONNECTED:
Serial.println("Http Event Disconnected");
break;
}
}
void setup(){
Serial.begin(115200);
Serial.println();
pinMode(LED_BUILTIN, OUTPUT);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
//WiFiClientSecure SSHclient;
//SSHclient.setCACert(server_certificate);
if(WiFi.status() == WL_CONNECTED) {
WiFiClientSecure SSHclient;
SSHclient.setCACert(server_certificate);
if (!SSHclient.connect(endpointHost, endpointPort))
Serial.println("Connection failed!");
else {
Serial.println("Connected to server!");
String request = "GET " + String(endpointURL) + " HTTP/1.1\r\n" +
"Host: " + String(endpointHost) + ":443\r\n" +
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" + "\r\n" +
"Cache-Control: no-cache" + "\r\n\r\n";
SSHclient.print(request);
while (SSHclient.connected()) {
String line = SSHclient.readStringUntil('\n');
//Serial.print(line);
if (line == "\r") {
//Serial.println("headers received");
break;
}
}
String json = "";
while (SSHclient.available()) {
char c = SSHclient.read();
// Serial.write(c);
json = json + String(c);
}
//Serial.println(String("")+"JSON大小:"+ json.length());
DynamicJsonDocument doc(json.length()*2);
deserializeJson(doc, json);
String latest_version = doc["version"].as<String>();
//Serial.print("version = ");
//Serial.println(latest_version);
if(latest_version > Current_version){
Serial.print("存在最新版本,等待更新");
Serial.print("Connected to ");
Serial.println(ssid);
HttpsOTA.onHttpEvent(HttpEvent);
Serial.println("Starting OTA");
HttpsOTA.begin(url, server_certificate);
Serial.println("Please Wait it takes some time ...");
while(latest_version > Current_version){
digitalWrite(LED_BUILTIN, HIGH);
delay(400);
digitalWrite(LED_BUILTIN, LOW);
delay(400);
digitalWrite(LED_BUILTIN, HIGH);
delay(400);
digitalWrite(LED_BUILTIN, LOW);
delay(400);
digitalWrite(LED_BUILTIN, HIGH);
delay(400);
digitalWrite(LED_BUILTIN, LOW);
delay(400);
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
digitalWrite(LED_BUILTIN, HIGH);
delay(400);
digitalWrite(LED_BUILTIN, LOW);
delay(400);
digitalWrite(LED_BUILTIN, HIGH);
delay(400);
digitalWrite(LED_BUILTIN, LOW);
delay(400);
digitalWrite(LED_BUILTIN, HIGH);
delay(400);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
otastatus = HttpsOTA.status();
if(otastatus == HTTPS_OTA_SUCCESS){
Serial.print("更新成功");
ESP.restart();
break;
}
}
}else{
Serial.print("当前为最新固件版本");
Serial.print(Current_version);
}
SSHclient.stop();
//Serial.println("closing connection");
}
} else { // end of WiFi Connection
Serial.println("WiFi Disconnected");
}
}
void loop(){
}
5、OTA更新的应用场景
1.智能手机和平板电脑:OTA可以用于更新操作系统、应用程序、驱动程序等软件,以及修复安全漏洞。
2.智能家居设备:OTA可以用于更新智能家居设备的固件,以增强其功能和性能。
3.汽车:OTA可以用于更新汽车的软件和地图数据,以提高驾驶体验和安全性。
4.工业设备:OTA可以用于更新工业设备的软件和配置,以提高生产效率和质量。
5.物联网设备:OTA可以用于更新物联网设备的固件和配置,以提高其性能和安全性。
总之,OTA可以应用于任何需要远程升级或配置的设备,为用户提供更好的使用体验和更高的安全性。
6、OTA升级的好处与缺点
OTA升级的好处:
OTA升级相比刷机升级,好处是显而易见的,OTA升级可以直接在手机中在线完成,只需要借助移动网络或者Wifi网络即可,并且升级无需备份数据,一般升级完成后,自动重启手机即可完成。而一般的刷固件升级,需要下载ROM固件,并且还需要刷机,刷机对于菜鸟朋友来说,是存在一定风险的。
OTA升级的缺点:
OTA升级没有明显缺点,不过升级过程中会下载一些升级包,会占据一些手机内存存储空间,另外如果手机系统非常卡,OTA升级系统也解决不了卡问题,但是如果通过刷固件升级,可以将系统恢复到最初的纯净状态,对系统流畅性有一定帮助,只不过刷机升级比较麻烦,并且会清空手机数据。
参考资料
OTA是什么:[OTA是什么](https://baike.baidu.com/reference/1381310)