OTA(Over-the-Air Technology)即空中下載技術,基於無線網路對裝置韌體、軟體或驅動進行更新。通過OTA升級,可以對物聯網裝置更新功能、修複漏洞、最佳化效能。本文介紹如何為接入物聯網平台的裝置進行OTA升級。
使用限制
使用OTA功能的裝置必須使用MQTT協議接入物聯網平台,裝置可以選擇MQTT協議或HTTPS協議下載升級包。
單個阿里雲帳號最多有500個升級包,帳號下所有RAM使用者共用配額。
升級包的數量、大小、格式和地區限制。
HTTPS協議下載:可以包括一個或多個檔案,單個檔案最大為1,000 MB。僅支援
.bin
、.dav
、.tar
、.gz
、.zip
、.gzip
、.apk
、.tar.gz
、.tar.xz
、.pack
格式的檔案。MQTT協議下載:僅包含一個檔案,且檔案大小不超過16 MB。目前僅支援中國華東2(上海)、華北2(北京)和華南1(深圳)地區。推薦使用物聯網平台提供的C語言Link SDK,開發MQTT下載檔案的能力。詳細內容,請參見範例程式碼說明。
工作原理
分發的裝置在被分發到目標執行個體後可正常進行OTA升級。
前提條件
將裝置接入物聯網平台。使用Link SDK的裝置,請參見擷取C Link SDK、裝置接入引導。搭載AliOS Things晶片的裝置,請參見AliOS Things文檔。
OTA升級步驟
本文樣本使用C語言Link SDK,其他語言SDK樣本請參見裝置接入概述。
步驟一:裝置上報版本號碼
配置OTA。
裝置上報目前的版本號。裝置需要在首次升級前上報版本號碼,建議只在系統啟動過程中上報一次,不需要周期迴圈上報。僅支援每次上報一個模組及對應的模組版本,如果需要上報多個模組的版本,請分次上報。上報的Topic和訊息格式參見文末的訊息格式。
步驟二:推送升級包資訊
添加升級包:為產品添加OTA模組和升級包。
模組:由使用者自訂,是同產品下裝置的不同可升級模組,例如韌體、軟體、驅動等。預設(default)模組表示整個裝置的韌體。
整包:完整的升級檔案,可以添加單個或多個升級包,如果添加多個樣本包必須使用C語言的Link SDK。整包升級前,裝置可不上報OTA模組版本。如不上報,配置批量升級時不能針對指定版本進行升級,具體說明,請參見發起升級批次任務。
差分:僅包含新版本升級包與之前版本的差異部分,裝置需要本地進行差分還原,並還原為完整升級包進行升級,差分升級可有效降低OTA升級次數消耗和裝置下載差分包的流量消耗。差分升級前,裝置必須上報OTA模組版本。
使用AliOS Things晶片的裝置,阿里雲提供差分包產生方法和差分還原演算法,請參見OTA差分工具使用指南。
其他裝置,需要您自行產生差分包並完成差分還原演算法開發。
(可選)驗證升級包:添加升級包時選擇升級包是否需要平台驗證為是,則在批量升級前,需選擇部分裝置用於測試。測試裝置升級成功後,才能使用升級包。
可以選擇是否由App確認升級後才能進行OTA升級,App確認升級的流程如下:
使用者自行開發App,平台不會主動推送升級訊息給裝置,需要App主動查詢。
App側調用ListOTAUnfinishedTaskByDevice,查詢未完成狀態的裝置升級作業。
App側調用ConfirmOTATask,確認升級任務後,平台才會主動推送升級訊息給裝置。
發起升級批次任務:物聯網平台向裝置批量下發升級相關資訊(升級包URL、版本、大小等)。發起批量升級後,在控制台顯示的裝置狀態是待升級或待確認。當物聯網平台接收到裝置上報的升級進度時,裝置升級正式開始,在控制台顯示的裝置狀態是升級中。
步驟三:裝置下載升級包
裝置擷取升級包資訊。裝置離線時不能接收OTA服務端推送的升級訊息,裝置再次上線後,OTA服務端驗證該裝置是否需要升級。如果需要升級,物聯網平台再次推送升級訊息給裝置,否則不推送訊息。
物聯網平台推送升級包資訊。裝置訂閱Topic:
/ota/device/upgrade/${YourProductKey}/${YourDeviceName}
,物聯網平台對裝置發起OTA升級請求後,裝置通過該Topic收到升級資訊。具體有以下兩種情況:發起升級任務時裝置線上,物聯網平台會直接推送升級相關資訊。
發起升級任務時裝置離線,之後裝置上線,物聯網平台會推送一次升級相關資訊。
裝置主動拉取升級包資訊。裝置向Topic發布訊息,物聯網平台收到訊息並通過另一Topic返回升級包資訊。拉取升級包的Topic和訊息格式參見文末的訊息格式。
物聯網平台發給裝置的HTTPS協議、MQTT協議的下載訊息格式參見文末的訊息格式。
裝置使用HTTPS協議或MQTT協議下載升級包。
裝置上報升級進度。上報進度的Topic和訊息格式參見文末的訊息格式。
重要如果裝置上報進度的間隔低於3秒,在物聯網平台控制台的OTA升級包詳情的批次詳情中,可能無法查看到上報的全部進度。
裝置上報最新版本號碼。裝置升級完成後,建議立即重啟裝置,裝置上線後,立即上報新的版本號碼。裝置上線請求和上報版本請求間隔不能超過2秒。
重要如果裝置上報的版本與OTA服務需求的版本一致就認為升級成功,反之認為失敗,這是物聯網平台判斷裝置升級成功的唯一條件。即使升級進度上報為100%,如果不上報新的版本號碼,可能因為超過裝置升級逾時時間導致升級失敗。
Topic:
/ota/device/inform/${YourProductKey}/${YourDeviceName}
訊息格式
{ "id": 1, "params": { "version": "2.0.0" } }
步驟四:查看升級結果
查看升級情況:查看目標裝置升級狀態、升級包資訊等。
查看升級包版本和成功率:查看升級後的版本分布和成功率分布統計,分析OTA升級失敗原因,進而提升裝置升級成功率。
相關文檔
裝置OTA升級失敗的常見問題和解決方案,請參見如何解決裝置OTA升級失敗問題。
可以在物聯網平台控制台,查詢雲端作業記錄。該日誌包含了物聯網平台、裝置、您的應用程式三者之間的互動通訊記錄。
物聯網平台可能返回給裝置端的錯誤碼及說明,請參見裝置端接收的錯誤碼。
如果需要將裝置上報的升級資訊,通過AMQP通道推送至您的伺服器,請參見配置AMQP服務端訂閱。OTA升級相關Topic資料,經過訊息轉寄後的資料格式,請參見資料格式。
訊息格式
上報版本號碼
Topic:
/ota/device/inform/${YourProductKey}/${YourDeviceName}
訊息格式
{ "id": 1, "params": { "version": "1.0.0", "module":"mcu" //該參數如果不填,表示預設版本號碼default } }
參數
類型
說明
id
String
訊息ID號。數字可為String或Long類型,以裝置端上報的資料類型為準。取值範圍為0~4294967295,且每個訊息ID在當前裝置中具有唯一性。
version
String
OTA模組版本。
module
String
OTA模組名。上報預設(default)模組的版本號碼時,可以不上報module參數。預設(default)模組代表整個裝置的韌體版本號碼。
主動拉取升級包
裝置發布訊息到Topic:
/sys/{productKey}/{deviceName}/thing/ota/firmware/get
。訊息格式
{ "id": "123", "version": "1.0", "params": { "module": "MCU" }, "method": "thing.ota.firmware.get" }
參數說明
參數
類型
說明
id
String
訊息ID號。String類型的數字,取值範圍0~4294967295,且每個訊息ID在當前裝置中具有唯一性。
version
String
協議版本,固定為1.0。
params
Object
請求參數。
module
String
升級包所屬的模組名。不指定則表示請求預設(default)模組的升級包資訊。
method
String
要求方法,取值thing.ota.firmware.get。
物聯網平台收到請求後,通過響應Topic:
/sys/{productKey}/{deviceName}/thing/ota/firmware/get_reply
,向裝置端返回升級包資訊。
HTTPS協議下載
單檔案包下載
{
"id": "123",
"code": 200,
"data": {
"size": 93796291,
"sign": "f8d85b250d4d787a9f483d89a974***",
"version": "10.0.1.9.20171112.1432",
"isDiff": 1,
"url": "https://the_firmware_url",
"signMethod": "MD5",
"md5": "f8d85b250d4d787a9f48***",
"module": "MCU",
"extData":{
"key1":"value1",
"key2":"value2",
"_package_udi":"{\"ota_notice\":\"升級底層網路攝影機驅動,解決視頻映像模糊的問題。\"}"
}
}
}
多檔案包下載
{
"code": "1000",
"data": {
"version": "2.0.0",
"isDiff": 1,
"signMethod": "MD5",
"files":[
{
"fileSize":432944,
"fileName":"file1-name",
"fileUrl":"https://***/nop***.tar.gz?Expires=1502955804&OSSAccessKeyId=***&Signature=***XJEH0qAKU%3D&security-token=CAISuQJ***",
"fileMd5":"93230c3bde425a9d***",
"fileSign":"93230c3bde425a9d****"
},
{
"fileSize":432945,
"fileName":"file2-name",
"fileUrl":"https://***/no***.tar.gz?Expires=1502955804&OSSAccessKeyId=***&Signature=***qAKU%3D&security-token=***q6Ft5B2y***",
"fileMd5":"93230c3bde425a92***",
"fileSign":"93230c3bde425a92****"
}
],
"module": "MCU",
"extData":{
"key1":"value1",
"key2":"value2",
"_package_udi":"{\"ota_notice\":\"升級底層網路攝影機驅動,解決視頻映像模糊的問題。\"}"
}
},
"id": 1626969597470,
"message": "success"
}
參數 | 類型 | 說明 |
id | Long | 訊息ID號。每個訊息ID在當前裝置中具有唯一性。 |
message | String | 結果資訊。 |
code | String | 狀態代碼。 |
version | String | 裝置升級包的版本資訊。 |
size | Long | 升級包檔案大小,單位:位元組。 OTA升級包中僅有一個升級包檔案時,包含該參數。 |
url | String | 升級包在Object Storage Service上的儲存地址。 OTA升級包中僅有一個升級包檔案,且下載協議為HTTPS時,包含該參數。 |
dProtocol | String | 升級包下載協議。 僅升級包下載協議為MQTT時,包含該參數。 |
streamId | Long | 通過MQTT協議下載OTA升級包時的唯一標識。 僅升級包下載協議為MQTT時,包含該參數。 |
streamFileId | Integer | 單個升級包檔案的唯一標識。 僅升級包下載協議為MQTT時,包含該參數。 |
isDiff | Long | 僅當升級包類型為差分時,訊息包含此參數。 取值為1,表示僅包含新版本升級包與之前版本的差異部分,需要裝置進行差分還原。 |
digestsign | String | OTA升級包檔案安全升級後的簽名。僅當OTA升級包開啟安全升級功能,才有此參數。開啟OTA升級包安全升級功能的方法,請參見添加升級包。 |
sign | String | OTA升級包檔案的簽名。 OTA升級包中僅有一個升級包檔案時,包含該參數。 |
signMethod | String | 簽名方法。取值:
對於Android差分升級包類型,僅支援MD5簽名方法。 |
md5 | String | 當簽名方法為MD5時,除了會給sign賦值外還會給md5賦值。 OTA升級包中僅有一個升級包檔案時,包含該參數。 |
module | String | 升級包所屬的模組名。模組名為default時,物聯網平台不下發module參數。 |
extData | Object | 升級批次標籤列表和推送給裝置的自訂資訊。 _package_udi表示自訂資訊的欄位。 單個標籤格式: |
files | Array | 多個升級包檔案的資訊列表。 OTA升級包中有多個檔案時,包含該參數。每個升級包檔案資訊如下:
|
MQTT協議下載
升級包下載協議為MQTT時,只支援單檔案包下載。裝置端擷取OTA升級包資訊後,可以選擇整包下載或分區下載。
整包下載
訊息格式
{ "id": "123", "code": 200, "data":{ "size":432945, "digestsign":"A4WOP***SYHJ6DDDJD9***", "version":"2.0.0", "isDiff":1, "signMethod":"MD5", "dProtocol":"mqtt", "streamId":1397345, "streamFileId":1, "md5":"93230c3bde***", "sign":"93230c3bde42***", "module":"MCU", "extData":{ "key1":"value1", "key2":"value2" } } }
參數說明
參數
類型
說明
id
Long
訊息ID號。每個訊息ID在當前裝置中具有唯一性。
message
String
結果資訊。
code
String
狀態代碼。
version
String
裝置升級包的版本資訊。
size
Long
升級包檔案大小,單位:位元組。
OTA升級包中僅有一個升級包檔案時,包含該參數。
url
String
升級包在Object Storage Service上的儲存地址。
OTA升級包中僅有一個升級包檔案,且下載協議為HTTPS時,包含該參數。
dProtocol
String
升級包下載協議。
僅升級包下載協議為MQTT時,包含該參數。
streamId
Long
通過MQTT協議下載OTA升級包時的唯一標識。
僅升級包下載協議為MQTT時,包含該參數。
streamFileId
Integer
單個升級包檔案的唯一標識。
僅升級包下載協議為MQTT時,包含該參數。
isDiff
Long
僅當升級包類型為差分時,訊息包含此參數。
取值為1,表示僅包含新版本升級包與之前版本的差異部分,需要裝置進行差分還原。
digestsign
String
OTA升級包檔案安全升級後的簽名。僅當OTA升級包開啟安全升級功能,才有此參數。開啟OTA升級包安全升級功能的方法,請參見添加升級包。
sign
String
OTA升級包檔案的簽名。
OTA升級包中僅有一個升級包檔案時,包含該參數。
signMethod
String
簽名方法。取值:
SHA256
MD5
對於Android差分升級包類型,僅支援MD5簽名方法。
md5
String
當簽名方法為MD5時,除了會給sign賦值外還會給md5賦值。
OTA升級包中僅有一個升級包檔案時,包含該參數。
module
String
升級包所屬的模組名。模組名為default時,物聯網平台不下發module參數。
extData
Object
升級批次標籤列表和推送給裝置的自訂資訊。
_package_udi表示自訂資訊的欄位。
單個標籤格式:
"key":"value"
。files
Array
多個升級包檔案的資訊列表。
OTA升級包中有多個檔案時,包含該參數。每個升級包檔案資訊如下:
fileSize:升級包檔案大小。
fileName:升級包檔案的名稱。
fileUrl、fileMd5、fileSign:含義與url、md5、sign相同。
可選:分區下載。擷取上面的升級包資訊後,裝置通過以下Topic分區下載OTA升級包檔案。
請求Topic:
/sys/${productKey}/${deviceName}/thing/file/download
響應Topic:
/sys/${productKey}/${deviceName}/thing/file/download_reply
請求訊息格式
{ "id": "123456", "version": "1.0", "params": { "fileToken":"1bb8***", "fileInfo":{ "streamId":1234565, "fileId":1 }, "fileBlock":{ "size":256, "offset":2 } } }
請求訊息的參數說明
參數
類型
說明
id
String
訊息ID號。String類型的數字,取值範圍0~4294967295,且每個訊息ID在當前裝置中具有唯一性。
version
String
協議版本,固定為1.0。
params
Object
請求參數。
fileToken
String
檔案的唯一標識Token,非必填參數。支援數字、英文字母、底線(_)和英文句號(.),不超過16個字元。
使用說明:
若傳入該參數,物聯網平台響應裝置請求時,會返回該參數,便於您在裝置端多檔案下載情境下,從響應訊息中確認下載的對應檔案。
若確認裝置端在下載檔案的請求和響應周期內,不需要對其他檔案發起下載請求,可不設定該參數。
fileInfo
Object
OTA升級包檔案資訊。
streamId
Long
通過MQTT協議下載OTA升級包時的唯一標識。
fileId
Integer
單個升級包檔案的唯一標識。
fileBlock
Object
檔案分區資訊。
size
Integer
請求下載的檔案分區大小,單位位元組,取值範圍為256~131072。若為最後一個檔案分區,取值範圍為1~131072。
offset
Integer
檔案分區對應位元組的起始地址。取值範圍為0~16777216。
響應訊息的結構
結構項
說明
JSON Bytes Length
表示響應資料中JSON字串對應的位元組數組長度,必須佔位2個位元組,高位位元組在前,低位位元組在後。
例如,響應的JSON字串使用UTF-8編碼轉碼成位元組數組的長度為十進位的87,對應十六進位57,則高位位元組為0x00,低位位元組為0x57。
JSON String Bytes
表示響應資料中JSON字串對應的位元組數組,編碼格式為UTF-8。具體內容,請參見下文的“響應的JSON資料格式”。
File Block Bytes
表示當前檔案分區的位元組數組,位元組順序按照相對於檔案頭的位移量從小至大排列。
CRC16/IBM
表示檔案分區的校正值,僅支援CRC16/IBM,佔位2個位元組,低位位元組在前,高位位元組在後。
例如,檔案分區的校正值為0x0809,則低位位元組為0x09,高位位元組為0x08。
響應訊息格式
{ "id": "123456", "code":200, "msg":"file size has exceeded the limit 16 MB", "data": { "fileToken":"1bb8***", "fileLength":1238848, "bSize":1491, "bOffset":2 } }
響應訊息的參數說明
參數
類型
說明
id
String
訊息ID號。String類型的數字,取值範圍0~4294967295,且每個訊息ID在當前裝置中具有唯一性。
此處訊息ID返回的是裝置請求中的訊息ID,即請求Topic
/sys/${productKey}/${deviceName}/thing/file/download
資料中的id。code
Integer
狀態代碼,200表示成功。
msg
String
請求失敗時,返回的錯誤資訊。
data
Object
返回裝置端的資料。
fileToken
String
檔案的唯一標識Token。若請求參數傳入了fileToken值,則返回該參數。
fileLength
Integer
檔案的總大小,單位位元組。
bSize
Integer
當前檔案分區的大小,單位位元組。
bOffset
Integer
當前檔案分區對應位元組的起始地址,與請求資料中的offset值相同。單位位元組。
上報升級進度
裝置發布訊息到Topic:
/ota/device/progress/${YourProductKey}/${YourDeviceName}
。訊息格式
{ "id": "123", "params": { "step": "-1", "desc": "OTA升級失敗,請求不到升級包資訊。", "module": "MCU" } }
格式說明
參數
類型
說明
id
String
訊息ID號。String類型的數字,取值範圍0~4294967295,且每個訊息ID在當前裝置中具有唯一性。
step
String
OTA升級進度。裝置上報的進度值及其描述資訊,可根據裝置實際升級情境在裝置端配置。裝置端配置方法,請參見範例程式碼說明。
1~100的整數:升級進度百分比。
-1
:升級失敗。-2
:下載失敗。-3
:校正失敗。-4
:燒寫失敗。
desc
String
當前步驟的描述資訊,長度不超過128個字元。如果發生異常,此欄位可承載錯誤資訊。
module
String
升級包所屬的模組名。模組的更多資訊,請參見添加升級包。
上報預設(default)模組的OTA升級進度時,可以不上報module參數。