什么是OTA?
百度百科:空中下載技術(Over-the-Air Technology; OTA),是通過移動通信的空中接口實現(xiàn)對移動終端設備及SIM卡數(shù)據(jù)進行遠程管理的技術。經(jīng)過公網(wǎng)多年的應用與發(fā)展,已十分成熟,網(wǎng)絡運營商通過OTA技術實現(xiàn)SIM卡遠程管理,還能提供移動化的新業(yè)務下載功能。
實際上,現(xiàn)在我們所說的OTA比百度百科的定義還要更廣泛,OTA的形式已經(jīng)不再局限于手機和SIM卡,只要涉及到遠程下載升級程序的方式我們都可以稱之為OTA。例如通過4G,5G,WiFI,藍牙等無線通訊進行下載升級的可以稱為OTA,通過U盤,RS485等串行接口進行升級的也可以稱之為OTA。
OTA的作用?
OTA的意義在于它在一定程度上突破了距離的限制,在沒有下載器沒有電腦不用到現(xiàn)場不用拆開設備等情況下完成固件的燒錄,極大的方便了產(chǎn)品的升級和維護,降低售后成本。
1 OTA原理簡介
在使用OTA時我們一般會把內(nèi)存分成三個部分:BootLoader,APP,Download(OTA)。
分區(qū) | 作用 |
---|---|
BootLoader | 存放引導程序 |
APP | 存放用戶程序,也就是我們自己寫的代碼 |
Download(OTA) | 存放要升級的程序固件,也就是新版本的代碼 |
OTA原理簡單介紹:
不管是在什么平臺,不管用的是什么MCU,要使用OTA都離不開BootLoader,BootLoader是一個統(tǒng)稱,它其實只是一段引導程序,在MCU啟動的時候會先運行這段代碼,判斷是否需要升級,如果不需要升級就跳轉到APP分區(qū)運行用戶代碼,如果需要升級則跳轉到Download分區(qū)進行固件解壓解碼等操作并且把該固件拷貝覆蓋到APP分區(qū),從而實現(xiàn)OTA。
怎么在Arduino下搭建OTA?
在明白了OTA升級原理之后我們再來看看Arduino下搭建OTA需要哪些東西,首先,APP部分用戶程序我們肯定是有的,Download分區(qū)的固件其實也是我們的新版本的APP程序,這兩部分都沒什么問題,關鍵在于BootLoader,這個是必須要搞的,而且還要根據(jù)自己的實際情況來使用,不同的升級方式,不同的MCU,不同的內(nèi)存地址等等都會有區(qū)別。我這里介紹是是一種比較簡單的方式,直接利用Arduino IDE現(xiàn)有的框架和開源源碼,通過TCP/IP協(xié)議來傳輸固件,從而實現(xiàn)OTA的功能,但是這種方式會有些局限性,具體有哪些局限性我放到最后再講。
2 Arduino IDE環(huán)境搭建
這個我具體就不說了,根據(jù)你自己用的MCU安裝好相應的庫就行了,既然你都開始研究OTA了應該不會連環(huán)境都沒搭好吧。如果有不懂的同學可以看下我之前發(fā)布的博客。
esp8266開發(fā)入門教程(基于Arduino)——環(huán)境安裝
使用VS code搭建Arduino IDE環(huán)境
3 編寫OTA測試代碼
我這里以ESP8266和ESP32為例編寫測試代碼,其他的MCU基本也是一致的,舉一反三即可。
硬件配置如下:
模塊 | 型號 | 說明 |
---|---|---|
ESP8266 | ESP-12F | 這是安信可的一款模組,內(nèi)部主要是用樂鑫的ESP8266EX再加上一個片外FLASH組成,開發(fā)板型號是NodeMCU-12F(CH340版本) |
ESP32 | ESP-WROOM-32 | MCU是樂鑫的一款芯片,開發(fā)板型號ESP32 DEVKITV1 |
具體的硬件參數(shù)和電路原理圖這里就不發(fā)出來了,不同廠家做的開發(fā)板引腳可能會有點差別。
示例代碼如下:
提示1:ESP8266和ESP32的庫是不同的,但是基本用法是類似的,我這個示例代碼做了ESP8266和ESP32的兼容,可以通用。
提示2:WIFI賬號和密碼要根據(jù)自己修改,代碼中的定義僅供參考。
提示3:PC端和設備端要在同一個局域網(wǎng)下。不懂什么是局域網(wǎng)的同學直接把兩個設備都連到同一個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升級測試
因為ESP8266和ESP32的測試結果是一樣的,這里就沒必要全部展示了,只貼一下ESP32的運行情況給你們做個參考。
先把代碼燒錄進去,通過串口打印的數(shù)據(jù),可以看到我們在代碼里面寫的用戶版本號以及wifi連接成功后的IP地址。
#define APP_VERSION "1.0.0" // app version
Serial.printf("nAPP version: %srn", APP_VERSION);
然后打開Arduino IDE,在 工具 -> 端口 一欄可以看到多出了一個網(wǎng)絡端口,這個IP就是我們ESP32的網(wǎng)絡IP地址。
提示:如果沒有出現(xiàn)該端口,要么是設備沒有連上網(wǎng)絡,要么是PC和設備不在同一個局域網(wǎng)。
選擇這個新的端口之后,我們就可以通過TCP/IP網(wǎng)絡協(xié)議燒錄程序。
我這里修改一下版本號,然后重新燒錄一遍。在Arduino IDE這里可以看到燒錄的日志跟之前串口燒錄不一樣了,顯示的是IP地址和下載進度條。(注:esp8266沒有顯示IP地址,只有進度條,不過不影響使用)
同樣的通過串口也能看到升級時運行的情況,Progress顯示的是OTA的升級進度,后面的百分比在升級過程中是會動的,從0%到100%。固件下載完成后設備會自動重啟,不需要手動進入下載模式。
注:這個顯示的結果跟串口助手也有一點關系,我這里用的是Xshell,如果用其它普通串口助手的話,Progress是會打印很多出很多個的,不過并不影響正常使用,如果不需要顯示這個進度,可以在代碼里面注釋掉。
結束語
好了,關于Arduino OTA的編程和使用方法就講到這里,其實這只是其中一種OTA的方式,而且有些局限性,因為PC端和MCU之間是通過局域網(wǎng)進行連接和傳輸固件的,在實際使用中,不可能所有設備和電腦都在同一網(wǎng)絡下,這樣的話就沒辦法做到遠程OTA了。最好的辦法還是通過一個公網(wǎng)IP或者服務器來連接設備,設備可以通過http進行固件的下載,這樣的話只要設備能連上網(wǎng)絡,連上服務器,就可以實現(xiàn)真正意義上的遠程OTA。
時間關系我這里就講這么多,后續(xù)有時間的話我會考慮再介紹一下其他方式的OTA。
想了解更多Arduino的內(nèi)容,可以關注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。還有什么問題的話,歡迎在評論區(qū)留言。如果這篇文章能夠幫到你,就…你懂得。