加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 1 OTA原理簡(jiǎn)介
    • 2 Arduino IDE環(huán)境搭建
    • 3 編寫(xiě)OTA測(cè)試代碼
    • 4 OTA升級(jí)測(cè)試
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Arduino應(yīng)用開(kāi)發(fā)——OTA(通過(guò)網(wǎng)絡(luò)升級(jí))

10/28 08:14
1608
閱讀需 14 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

什么是OTA?

百度百科:空中下載技術(shù)(Over-the-Air Technology; OTA),是通過(guò)移動(dòng)通信的空中接口實(shí)現(xiàn)對(duì)移動(dòng)終端設(shè)備及SIM卡數(shù)據(jù)進(jìn)行遠(yuǎn)程管理的技術(shù)。經(jīng)過(guò)公網(wǎng)多年的應(yīng)用與發(fā)展,已十分成熟,網(wǎng)絡(luò)運(yùn)營(yíng)商通過(guò)OTA技術(shù)實(shí)現(xiàn)SIM卡遠(yuǎn)程管理,還能提供移動(dòng)化的新業(yè)務(wù)下載功能。

實(shí)際上,現(xiàn)在我們所說(shuō)的OTA比百度百科的定義還要更廣泛,OTA的形式已經(jīng)不再局限于手機(jī)和SIM卡,只要涉及到遠(yuǎn)程下載升級(jí)程序的方式我們都可以稱之為OTA。例如通過(guò)4G,5G,WiFI,藍(lán)牙無(wú)線通訊進(jìn)行下載升級(jí)的可以稱為OTA,通過(guò)U盤(pán),RS485串行接口進(jìn)行升級(jí)的也可以稱之為OTA。

OTA的作用?

OTA的意義在于它在一定程度上突破了距離的限制,在沒(méi)有下載器沒(méi)有電腦不用到現(xiàn)場(chǎng)不用拆開(kāi)設(shè)備等情況下完成固件的燒錄,極大的方便了產(chǎn)品的升級(jí)和維護(hù),降低售后成本。

1 OTA原理簡(jiǎn)介

在使用OTA時(shí)我們一般會(huì)把內(nèi)存分成三個(gè)部分:BootLoader,APP,Download(OTA)。

分區(qū) 作用
BootLoader 存放引導(dǎo)程序
APP 存放用戶程序,也就是我們自己寫(xiě)的代碼
Download(OTA) 存放要升級(jí)的程序固件,也就是新版本的代碼

OTA原理簡(jiǎn)單介紹:

不管是在什么平臺(tái),不管用的是什么MCU,要使用OTA都離不開(kāi)BootLoader,BootLoader是一個(gè)統(tǒng)稱,它其實(shí)只是一段引導(dǎo)程序,在MCU啟動(dòng)的時(shí)候會(huì)先運(yùn)行這段代碼,判斷是否需要升級(jí),如果不需要升級(jí)就跳轉(zhuǎn)到APP分區(qū)運(yùn)行用戶代碼,如果需要升級(jí)則跳轉(zhuǎn)到Download分區(qū)進(jìn)行固件解壓解碼等操作并且把該固件拷貝覆蓋到APP分區(qū),從而實(shí)現(xiàn)OTA。

怎么在Arduino下搭建OTA?

在明白了OTA升級(jí)原理之后我們?cè)賮?lái)看看Arduino下搭建OTA需要哪些東西,首先,APP部分用戶程序我們肯定是有的,Download分區(qū)的固件其實(shí)也是我們的新版本的APP程序,這兩部分都沒(méi)什么問(wèn)題,關(guān)鍵在于BootLoader,這個(gè)是必須要搞的,而且還要根據(jù)自己的實(shí)際情況來(lái)使用,不同的升級(jí)方式,不同的MCU,不同的內(nèi)存地址等等都會(huì)有區(qū)別。我這里介紹是是一種比較簡(jiǎn)單的方式,直接利用Arduino IDE現(xiàn)有的框架和開(kāi)源源碼,通過(guò)TCP/IP協(xié)議來(lái)傳輸固件,從而實(shí)現(xiàn)OTA的功能,但是這種方式會(huì)有些局限性,具體有哪些局限性我放到最后再講。

2 Arduino IDE環(huán)境搭建

這個(gè)我具體就不說(shuō)了,根據(jù)你自己用的MCU安裝好相應(yīng)的庫(kù)就行了,既然你都開(kāi)始研究OTA了應(yīng)該不會(huì)連環(huán)境都沒(méi)搭好吧。如果有不懂的同學(xué)可以看下我之前發(fā)布的博客。

esp8266開(kāi)發(fā)入門(mén)教程(基于Arduino)——環(huán)境安裝

ESP32 Arduino開(kāi)發(fā)環(huán)境搭建

使用VS code搭建Arduino IDE環(huán)境

3 編寫(xiě)OTA測(cè)試代碼

我這里以ESP8266和ESP32為例編寫(xiě)測(cè)試代碼,其他的MCU基本也是一致的,舉一反三即可。

硬件配置如下:

模塊 型號(hào) 說(shuō)明
ESP8266 ESP-12F 這是安信可的一款模組,內(nèi)部主要是用樂(lè)鑫的ESP8266EX再加上一個(gè)片外FLASH組成,開(kāi)發(fā)板型號(hào)是NodeMCU-12F(CH340版本)
ESP32 ESP-WROOM-32 MCU是樂(lè)鑫的一款芯片,開(kāi)發(fā)板型號(hào)ESP32 DEVKITV1

具體的硬件參數(shù)和電路原理圖這里就不發(fā)出來(lái)了,不同廠家做的開(kāi)發(fā)板引腳可能會(huì)有點(diǎn)差別。

示例代碼如下:
提示1:ESP8266和ESP32的庫(kù)是不同的,但是基本用法是類似的,我這個(gè)示例代碼做了ESP8266和ESP32的兼容,可以通用。
提示2:WIFI賬號(hào)和密碼要根據(jù)自己修改,代碼中的定義僅供參考。
提示3:PC端和設(shè)備端要在同一個(gè)局域網(wǎng)下。不懂什么是局域網(wǎng)的同學(xué)直接把兩個(gè)設(shè)備都連到同一個(gè)WIFI即可。

#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#else
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#endif

#define APP_VERSION "1.0.0"        // app version

#ifndef STASSID
#define STASSID "test"             // wifi user
#define STAPSK  "123456789"        // wifi password
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {
    Serial.begin(115200);
    Serial.printf("nAPP version: %srn", APP_VERSION);
    Serial.println("Booting");
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.waitForConnectResult() != WL_CONNECTED) 
    {
        Serial.println("Connection Failed! Rebooting...");
        delay(5000);
        ESP.restart();
    }

    ArduinoOTA.onStart([]() {
        String type;
        if (ArduinoOTA.getCommand() == U_FLASH) {
            type = "sketch";
        }
        else { // U_FS
            type = "filesystem";
        }

        // NOTE: if updating FS this would be the place to unmount FS using FS.end()
        Serial.println("Start updating " + type);
    });

    ArduinoOTA.onEnd([]() {
        Serial.println("nEnd");
    });

    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("Progress: %u%%r", (progress / (total / 100)));
    });

    ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) {
            Serial.println("Auth Failed");
        }
        else if (error == OTA_BEGIN_ERROR) {
            Serial.println("Begin Failed");
        }
        else if (error == OTA_CONNECT_ERROR) {
            Serial.println("Connect Failed");
        }
        else if (error == OTA_RECEIVE_ERROR) {
            Serial.println("Receive Failed");
        }
        else if (error == OTA_END_ERROR) {
            Serial.println("End Failed");
        }
    });
    ArduinoOTA.begin();
    Serial.println("Ready");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
}

void loop() {
    ArduinoOTA.handle();
}

4 OTA升級(jí)測(cè)試

因?yàn)镋SP8266和ESP32的測(cè)試結(jié)果是一樣的,這里就沒(méi)必要全部展示了,只貼一下ESP32的運(yùn)行情況給你們做個(gè)參考。

先把代碼燒錄進(jìn)去,通過(guò)串口打印的數(shù)據(jù),可以看到我們?cè)诖a里面寫(xiě)的用戶版本號(hào)以及wifi連接成功后的IP地址。

#define APP_VERSION "1.0.0"        // app version

Serial.printf("nAPP version: %srn", APP_VERSION);

在這里插入圖片描述

然后打開(kāi)Arduino IDE,在 工具 -> 端口 一欄可以看到多出了一個(gè)網(wǎng)絡(luò)端口,這個(gè)IP就是我們ESP32的網(wǎng)絡(luò)IP地址。

提示:如果沒(méi)有出現(xiàn)該端口,要么是設(shè)備沒(méi)有連上網(wǎng)絡(luò),要么是PC和設(shè)備不在同一個(gè)局域網(wǎng)。

在這里插入圖片描述

選擇這個(gè)新的端口之后,我們就可以通過(guò)TCP/IP網(wǎng)絡(luò)協(xié)議燒錄程序。

我這里修改一下版本號(hào),然后重新燒錄一遍。在Arduino IDE這里可以看到燒錄的日志跟之前串口燒錄不一樣了,顯示的是IP地址和下載進(jìn)度條。(注:esp8266沒(méi)有顯示IP地址,只有進(jìn)度條,不過(guò)不影響使用)

在這里插入圖片描述
同樣的通過(guò)串口也能看到升級(jí)時(shí)運(yùn)行的情況,Progress顯示的是OTA的升級(jí)進(jìn)度,后面的百分比在升級(jí)過(guò)程中是會(huì)動(dòng)的,從0%到100%。固件下載完成后設(shè)備會(huì)自動(dòng)重啟,不需要手動(dòng)進(jìn)入下載模式。

注:這個(gè)顯示的結(jié)果跟串口助手也有一點(diǎn)關(guān)系,我這里用的是Xshell,如果用其它普通串口助手的話,Progress是會(huì)打印很多出很多個(gè)的,不過(guò)并不影響正常使用,如果不需要顯示這個(gè)進(jìn)度,可以在代碼里面注釋掉。

在這里插入圖片描述

結(jié)束語(yǔ)

好了,關(guān)于Arduino OTA的編程和使用方法就講到這里,其實(shí)這只是其中一種OTA的方式,而且有些局限性,因?yàn)镻C端和MCU之間是通過(guò)局域網(wǎng)進(jìn)行連接和傳輸固件的,在實(shí)際使用中,不可能所有設(shè)備和電腦都在同一網(wǎng)絡(luò)下,這樣的話就沒(méi)辦法做到遠(yuǎn)程O(píng)TA了。最好的辦法還是通過(guò)一個(gè)公網(wǎng)IP或者服務(wù)器來(lái)連接設(shè)備,設(shè)備可以通過(guò)http進(jìn)行固件的下載,這樣的話只要設(shè)備能連上網(wǎng)絡(luò),連上服務(wù)器,就可以實(shí)現(xiàn)真正意義上的遠(yuǎn)程O(píng)TA。

時(shí)間關(guān)系我這里就講這么多,后續(xù)有時(shí)間的話我會(huì)考慮再介紹一下其他方式的OTA。

想了解更多Arduino的內(nèi)容,可以關(guān)注一下博主,后續(xù)我還會(huì)繼續(xù)分享更多的經(jīng)驗(yàn)給大家。還有什么問(wèn)題的話,歡迎在評(píng)論區(qū)留言。如果這篇文章能夠幫到你,就…你懂得。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜