ESP32-CAM OTA解决方案介绍,自动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)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值