物聯網裝置OTA軟體升級之:升級包下載過程之旅

sewain發表於2021-06-06

OTA概述

大家好,我是一個軟體升級包。這幾天呢,我將會進行一次神奇的網路之旅,從開發者的電腦中,一直跑到終端嵌入式裝置中。

大家都把我的這個旅遊過程叫做 OTA,也就是線上升級。

那麼啥叫 OTA 呢?全稱是:Over the Air Technology,其實就是通過網路來把一個新的軟體包從伺服器上下載下來,更新到裝置上。

首先有一個問題:為什麼叫軟體升級包,而不叫韌體升級包呢?

其實在本質上,韌體也是屬於軟體,大家都是用程式碼寫出來的嘛!

雖然這兩個說法很近似,但是有一部分小夥伴還是在狹義上對它們進行了一些區分。

既然如此,我們也就暫且把它倆進行一下區別:

  1. 韌體:是指一些沒有檔案系統的嵌入式裝置中,把 Flash 分成不同的功能分割槽。可執行程式需要放在某個固定的起始位置,才能被 bootloader 進行啟動。

  2. 軟體:是指具有檔案系統的嵌入式裝置,可執行程式直接放在檔案系統中。當裝置啟動之後,作業系統會啟動檔案系統中的可執行程式。

沒有檔案系統的嵌入式裝置

帶有檔案系統的裝置:

我知道以上這樣的區分方式不是很嚴謹,但是誰又說得清楚嚴謹的定義是什麼呢?

暫且先這麼來區分,只要不影響對文章的理解就可以了!

一個嵌入式裝置在進行軟體升級的時候,從巨集觀的角度看,可以分為2 個階段:

  1. 下載升級包;

  2. 解壓升級包,寫入 flash 或檔案系統;

今天呢,主要以第 1 階段為主,帶你看一下我是如何從開發者的電腦裡,一步一步的被嵌入式裝置下載到本地的。

下面是一個完整的過程,讓您先睹為快!


上傳升級包

為了便於描述,我們來假設一個場景:執行在裝置中的軟體一共有 3 個檔案:

  1. main 檔案:可執行程式;

  2. config.ini:配置檔案;

  3. mylib.so:一個動態庫檔案,裡面包含一個演算法,被 main 檔案呼叫;

目前呢,裝置中執行的版本是 V1.0,現在開發人員對 mylib.so 庫中的演算法進行了優化,升級為 V2.0 版本,現在需要把這個新版本升級到嵌入式裝置中。

首先第一步需要做的事情,我們們用腳後跟都能想得到,那就是把 V2.0 版本的程式軟體上傳到檔案伺服器中。

有一點提醒一下:很多雲平臺都會把應用伺服器和檔案伺服器進行區分。當然,如果僅僅是測試的話,它倆可以在同一臺物理伺服器上共存。

比如:亞馬遜的 AWS 平臺,就是把升級包上傳到 S3 伺服器中。

現在要對 V2.0 版本的程式進行打包了,在這裡,除了 mainconfig.inimylib.so3 個檔案之外,我們還把另一個指令碼檔案 upgrade.sh 也放進打包檔案中。

這個檔案的作用暫且不說,到後面會為您揭曉答案。

Bingo - V2.0 版本的升級包誕生了:app_v2_0.tgz,上傳到檔案伺服器上之後,地址為:http://fileserve/app_v2_0.tgz


上傳升級包描述檔案

現在,V2.0 版本的升級包已經上傳到檔案伺服器中了,是否現在就可以命令嵌入裝置去下載、升級了呢?

我們知道,在一個物聯網系統中,一般都是存在著很多個終端裝置的。

這些裝置可能處於正在執行狀態、也可能處於斷電狀態,而且我們們也不能假設所有的裝置都在同一個時間點進行升級。

再而且,一個裝置進行升級之後,就變成了最新的 V2.0 版本,那麼這個裝置就應該有能力知道伺服器上的最新版本是 V2.0 版本,這樣它就不需要升級了。

因此,還需要一個新的檔案來描述檔案伺服器中的 V2.0 版本的升級包,就叫它:升級包描述檔案 app_desc.json,它的內容是 json 格式的字串:

version 欄位描述了檔案伺服器上升級包的版本,這樣的話,裝置就可以知道到伺服器中的最新版本。

url 欄位描述了升級包的下載地址,裝置如果發現自己的版本低於 version 欄位中的版本,就可以從這個地址下載新的升級包。

md5 欄位描述了伺服器中最新升級包的指紋資訊,當裝置把伺服器上的升級包下載之後,需要計算一下升級包的 MD5 值,然後與這裡的 md5 欄位進行比較,如果相同的話,說明下載的升級包沒有問題,沒有被惡意的傢伙掉包。

瞭解了升級包描述檔案 app_desc.json 的作用之後,這個檔案就被上傳到應用伺服器中了。


下載升級包描述檔案

此時,作為升級包的我,已經靜靜的躺在檔案伺服器中了,我的兄弟升級包描述檔案 app_desc.json 呢,也在應用伺服器中準備就緒了,現在就等著嵌入式裝置開始升級。

萬事俱備,只欠東風了!應該說只欠一個觸發嵌入式裝置進行升級的動作了!

那麼,應該在什麼時候?由誰?來告訴裝置:你正在執行的軟體太舊了,伺服器上現在有最新的版本,你去升級一下吧!

這個問題的答案就是:八仙過海,各顯神通了!

比如:

  1. 亞馬遜的 AWS 平臺,是通過在雲平臺中部署一個 job,來通知每一個需要升級的裝置;

  2. 也可以通過一個手機 APP,向某一個嵌入式裝置主動發起一個指令:嘿,老兄,請升級一下你的軟體;

當終端裝置收到升級命令之後,第一步就是下載升級包描述資訊

下載之後,解析這個 json 格式的文字內容,提取出 version 資訊之後,與當前正在執行的軟體版本進行比較。

如果伺服器中的版本比較新,那麼就繼續提取 url 欄位中的升級包下載地址,然後開始從檔案伺服器中下載新的升級包。

如果當前執行的版本已經是最新的了,那就到此結束!


下載升級包

到了下載升級包的過程就簡單了,你可以直接用 wget 等工具來下載,也可以利用 curl 庫來手寫下載程式碼。

總之,你可以有一萬種方式把我下載到裝置中。

下載完成之後,有一件很重要的事情千萬別忘記了,那就是:檢查下載的升級包是否正確!

還記得升級包描述檔案中的 md5 欄位嗎?那就是我的指紋資訊。

你需要首先計算一下下載的升級包的 md5 值,然後與升級包描述檔案中的 md5 欄位中的值進行比對,如果完全一致,那就放心大膽的開始解壓、升級吧!


解壓升級包

欲知後事如何,請聽下回分解!


------ End ------

Hi~您好,我是道哥,一枚嵌入式開發老兵。


這是我的個人微信,做個點贊之交也不錯哦!

讓知識流動起來,越分享越幸運!

星標公眾號,能更快找到我!


推薦閱讀

【1】C語言指標-從底層原理到花式技巧,用圖文和程式碼幫你講解透徹
【2】一步步分析-如何用C實現物件導向程式設計
【3】原來gdb的底層除錯原理這麼簡單
【4】內聯彙編很可怕嗎?看完這篇文章,終結它!
【5】都說軟體架構要分層、分模組,具體應該怎麼做

相關文章