一文弄清物聯網的OTA
許多嵌入式系統部署在人類操作員很難或無法訪問的地方。 對於物聯網應用程式來說尤其如此,物聯網應用程式通常數量較大,電池壽命有限。 一些例子是監視人或機器健康狀況的嵌入式系統。 這些挑戰,再加上快速的軟體生命週期,導致許多系統需要對OTA更新提供支援。
OTA更新以新的軟體替代了嵌入式系統中微控制器或微處理器上的軟體。 雖然許多人非常熟悉他們的移動裝置上的 OTA 更新,但是在資源受限的系統上的設計和實現會帶來許多不同的挑戰。
在IoT固/軟體更新及開源選項一文中,學習了一些開源的技術,在這裡,將描述幾種不同的OTA更新軟體設計,並討論它們的利弊,並將瞭解兩個超低功耗微控制器的硬體特性如何在 OTA更新軟體中得到的利用。
構建基礎
嵌入式系統中的CS架構
OTA升級用新的軟體取代了裝置上現有的軟體,新的軟體通過無線網路下載。 在嵌入式系統中,執行這個軟體的裝置通常是一個微控制器。 微控制器是一種小型計算裝置,具有有限的儲存器,速度和功耗。 微控制器通常包含一個微處理器(核心)以及用於特定操作(外圍裝置)的數字硬體。 超低功耗微控制器通常在主動模式下消耗30 微安/Mhz到40微安/Mhz,是這種型別應用的理想選擇。
在這些微控制器上使用特定的硬體外設,並將其設定為低功耗模式,是 OTA 更新軟體設計的重要組成部分。 圖1顯示了一個可能需要 OTA 更新的嵌入式系統示例。 這裡的一個微控制器連線著一個無線模組和感測器,它可以用在物聯網應用中,通過感測器收集環境資料,並定期用無線模組報告。 系統的這一部分稱為邊緣節點或客戶端,是 OTA 更新的目標。 系統的另一部分稱為雲或伺服器,是新軟體的提供者。 伺服器和客戶端通過使用收發信機(無線電)進行通訊。
圖1 嵌入式系統中的客戶機/伺服器體系結構
OTA 的軟體本質
OTA更新流程的大部分工作是將新軟體從伺服器轉移到客戶端。 當軟體從原始碼格式轉換為二進位制格式後,軟體以位元組序列的形式傳輸。 轉換過程包括編譯原始碼檔案(例如 c、 cpp) ,將它們連結到一個可執行檔案(例如 exe、 elf)中,然後將可執行檔案轉換為可移植的二進位制檔案格式(例如 bin、 hex)。這些檔案格式包含一個位元組序列,屬於微控制器記憶體的特定地址。
通常,通過無線鏈路傳送的資訊概念化為資料,例如更改系統狀態或系統收集的感測器資料的命令。 在 OTA 更新的情況下,資料是二進位制格式的新軟體。 在許多情況下,二進位制檔案太大,無法將一次傳輸從伺服器傳送到客戶機,這意味著需要將二進位制檔案放入單獨的資料包中,這個過程被稱為打包。 為了更好地將這一過程視覺化,圖2演示了不同版本的軟體如何生成不同的二進位制檔案,從而在 OTA 更新期間傳送不同的資料包。 在這個簡單的示例中,每個資料包包含8個位元組的資料,前4個位元組表示客戶機記憶體中的地址,用於儲存後4個位元組的資料。
圖2 軟體應用的二進位制轉換和打包過程
OTA的主要挑戰
基於這種對 OTA 更新流程的描述,OTA 更新解決方案必須解決三大挑戰。
第一個挑戰與記憶體有關。 軟體解決方案必須將新的軟體應用程式組織到客戶端裝置的易失性或非易失性儲存器中,以便在更新過程完成時執行。 解決方案必須確保以前的軟體版本在新軟體出現問題時作為後備應用程式保留下來。 此外,必須保留客戶端裝置的狀態之間的重置和電源週期,如軟體的版本,已經目前正在執行在記憶體中的位置。
第二個挑戰是通訊。新軟體必須以離散資料包的形式從伺服器傳送到客戶機,每個資料包針對客戶機記憶體中的特定地址。 軟體設計中必須考慮資料包的分組方案、分組結構和傳輸協議。
最後一個主要挑戰是安全問題。 隨著新的軟體從伺服器無線傳送到客戶端,必須確保伺服器是可信的。 這種安全挑戰稱為身份驗證,還必須確保新軟體對任何觀察者進行模糊處理,因為它可能包含敏感資訊。這種安全挑戰稱為保密性。 安全的最後一個要素是完整性,確保新軟體在空中傳送時不會損壞。
引導載入程式
理解啟動順序
主引導載入程式是永久駐留在微控制器只讀記憶體上的軟體應用程式。 主引導載入程式駐留的記憶體區域稱為資訊空間,使用者有時無法訪問該區域。 這個應用程式在每次重置時執行,通常執行一些必要的硬體初始化,並可能載入使用者軟體到記憶體中。
但是,如果微控制器包含片內非易失性記憶體,如快閃記憶體,啟動載入程式不需要做任何載入,只需將控制權轉移到快閃記憶體中的程式。 如果主引導載入程式沒有對 OTA 更新的任何支援,則有必要使用第二階段引導載入程式(SSBL)。 與主引導載入程式一樣,SSBL 將在每次reset時執行,但將實現OTA更新過程的一部分。 引導順序如圖3所示。 在這裡將學習為什麼需要第二階段引導載入程式,以及如何指定此應用程式的角色是一個關鍵的設計權衡。
圖3 用SSBL實現記憶體對映和引導流的示例
不使用SSBL的問題
從概念上講,省略 SSBL 將所有的OTA更新功能放到使用者應用程式中似乎更簡單,因為它將允許現有的軟體框架、作業系統和裝置驅動程式無縫地用於OTA過程。 選擇這種方法的系統記憶體對映和引導順序如圖4所示。
圖4 沒有SSBL的記憶體對映和啟動流
應用程式A是原來的應用,是部署在微控制器的控制域。 此應用程式包含與 OTA 更新相關的軟體,當伺服器請求時,將利用該軟體下載應用程式 B。 在完成下載並驗證了應用程式B 之後,應用程式A將通過嚮應用程式B執行reset指令將控制轉移到應用程式B。 reset處理程式是一小段程式碼,它是軟體應用程式的入口點,並在重置時執行。 在這種情況下,通過執行分支(相當於函式呼叫)來模仿reset。
這種做法有兩個主要問題:
-
許多嵌入式軟體應用程式使用實時作業系統(RTOS) ,它允許將軟體分解成併發任務,每個任務在系統中有不同的職責。 例如,圖1所示的應用程式可能具有讀取感測器、在感測器資料上執行演算法以及與無線模組連線的 RTOS 任務。 RTOS本身總是處於活動狀態,負責基於非同步事件或特定的時間延遲在這些任務之間切換。 因為其他任務將保持在後臺執行,所以從 RTOS 任務分支到一個新的程式是不安全的, 唯一安全的方法是通過通過重置來終止一個程式與實時作業系統。
-
基於圖4,解決上一個問題的辦法是將主引導載入程式切換到應用程式B,而不是應用程式A。然而,在一些微控制器上,主引導載入程式總是執行中斷向量表(IVT)的程式,IVT 是應用程式中描述中斷處理函式的關鍵部分,位於地址0。 這意味著需要某種形式的IVT重新定位到應用程式B的重置對映。 如果電源重啟在 IVT 重新定位過程中發生,則可能使系統處於永久性的破壞狀態。
如圖3所示,通過在地址0處設定 SSBL 可以減輕這些問題。 由於SSBL是一個非RTOS程式,它可以安全地切換到一個新的應用程式。無需對電源重啟關注,因為 IVT 的 SSBL 在地址0是從來沒有重置的。
SSBL 的功能
瞭解了 SSBL 及其與應用軟體的關係,那這個 SSBL 做什麼呢? 最起碼,程式必須確定當前應用程式是什麼(開始的位置) ,然後再切換到該地址。 如圖3所示,微控制器記憶體中各種應用程式的位置通常儲存在一個目錄(ToC)中。 這是持久記憶體的一個共享區域,SSBL和應用程式軟體都使用它們來相互通訊。
當 OTA 更新過程完成時,ToC 將使用新的應用程式資訊進行更新。 OTA更新功能的一部分也可以推送到SSBL。在開發 OTA 更新軟體時,“確定哪些部分”是一個重要的設計決策。 上面描述的最小 SSBL 將是非常簡單的,易於驗證,並且很可能不需要在應用程式的生命週期中進行修改。
但是,這意味著每個應用程式必須負責下載並驗證下一個應用程式。 這可能導致無線堆疊、裝置韌體和 OTA 更新軟體方面的程式碼重複。 另一方面,可以選擇將整個 OTA 更新過程推送到 SSBL。 在這種情況下,應用程式只需在 ToC 中設定一個標誌來請求更新,然後執行復位。 SSBL然後執行下載序列和驗證過程。 這將最大限度地減少程式碼重複,並簡化應用程式特定的軟體。
這帶來了一個新的挑戰,可能需要更新 SSBL 本身(即升級更新程式碼)。 最後,決定在 SSBL 中放置什麼功能將取決於客戶端裝置的記憶體約束、下載應用程式之間的相似性以及 OTA 更新軟體的可移植性。
設計權衡: 快取和壓縮
OTA更新軟體中的另一個關鍵設計決策是在 OTA 更新過程中如何在記憶體中組織收到的應用程式。 微控制器中兩種典型的儲存器是非易失性儲存器(例如,快閃記憶體)和易失性儲存器(例如,SRAM)。 快閃記憶體將用於儲存程式程式碼和應用程式的只讀資料,以及其他系統級資料,如 ToC 和事件日誌。 SRAM將用於儲存軟體應用程式的可修改部分,例如非常量全域性變數和堆疊。 圖2所示的軟體應用程式二進位制程式碼只包含程式在非易失性儲存器中的部分。 在啟動例程期間,應用程式將初始化屬於可變記憶體中的部分。
在 OTA 更新過程中,每當客戶端裝置從伺服器接收到一個包含部分二進位制的資料包時,它將被儲存在 SRAM 中。 這個資料包可以是壓縮的,也可以是未壓縮的。 壓縮應用程式二進位制檔案的好處是它的體積更小,允許傳送的資料包更少,在下載過程中 SRAM 中儲存它們所需的空間更少。 這種方法的缺點是壓縮和解壓縮會給更新過程增加額外的處理時間,而且必須在 OTA 更新軟體中捆綁相關程式碼。
由於新的應用軟體在升級過程中位於快閃記憶體中,但是在升級過程中卻進入了 SRAM,所以 OTA 的升級軟體在升級過程中需要對快閃記憶體進行寫操作。 在 SRAM 中臨時儲存新應用程式稱為快取。 在高層,OTA 更新軟體可以採取三種不同的方法進行快取。
-
禁用快取記憶體: 每當包含一部分新應用程式的資料包到達時,將其寫到快閃記憶體中的目標位置。 此方案非常簡單,可以最小化 OTA 更新軟體的邏輯量,但是它要求新應用程式的快閃記憶體區域被完全擦除。 這種方法削弱了快閃記憶體,增加了開銷。
-
部分快取: 保留一個 SRAM 區域用於快取,當新資料包到達時將它們儲存在 SRAM 的區域中。 當區域填滿時,通過將資料寫入快快閃記憶體儲器來清空它。 如果資料包無序到達,或者在新的應用程式二進位制檔案中存在間隙,這可能會變得很複雜,因為需要一種將 SRAM 地址對映到快閃記憶體地址的方法。 一種策略是將快取記憶體作為快閃記憶體的一部分映象。 快閃記憶體分為小區域的頁面,這是寫操作的最小劃分。 由於這種自然的劃分,一個好的方法是在 SRAM 中快取一頁快閃記憶體,當它填滿或者下一個資料包屬於不同的頁面時,通過寫該頁面的快閃記憶體來重新整理快取。
-
完全快取: 在 OTA 更新過程中,將整個新應用程式儲存在 SRAM 中,並只在從伺服器完全下載後將其寫入快閃記憶體。 這種方法通過減少對快閃記憶體的寫入次數,避免了 OTA 更新軟體複雜的快取邏輯,克服了以往方法的缺點。 但是,這將限制下載新應用程式的大小,因為系統上可用 SRAM 的數量通常遠小於可用快閃記憶體的數量。
圖5 利用 SRAM 實現一頁快取記憶體
在 OTA 更新過程中使用部分快取的第二種方案如圖5所示,其中圖3和圖4中應用程式 a 的快閃記憶體部分被放大,而 SSBL 的 SRAM 功能儲存器對映圖則如圖所示。 顯示了一個2 kB 大小的 flash 頁面示例。最終,這個設計決策將根據新應用程式的大小和允許的 OTA 更新軟體的複雜性來確定。
安全及通訊
設計權衡: 軟體 vs 協議
OTA更新解決方案還必須解決安全性和通訊問題。 許多類似於圖1所示的系統將具有在硬體和軟體中實現的通訊協議,用於正常的(非OTA更新相關的)系統行為,如交換感測器資料。 這意味著在伺服器和客戶機之間已經建立了一種(可能是安全的)無線通訊方法。 像圖1這樣的嵌入式系統可能使用的通訊協議,例如,BLE或6LoWPAN。 有時這些協議支援安全性和資料交換,OTA更新軟體可以更新過程中利用這些安全性和資料交換。
必須構建 OTA 更新軟體中的通訊功能,但最終將取決於現有通訊協議提供了多少抽象。 現有的通訊協議是在伺服器和客戶機之間傳送和接收檔案的工具,OTA 更新軟體可以簡單地利用這些工具進行下載。 然而,如果通訊協議比較原始,並且只能傳送原始資料,則 OTA 更新軟體可能需要執行分包,並隨新的應用程式二進位制檔案提供元資料。 這也適用於安全挑戰。 如果通訊協議不支援,則 OTA 更新軟體可能負責解密通過空中傳送的用於保密的位元組。
總之,構建諸如自定義包結構、伺服器/客戶端同步、加密和金鑰交換功能,並把它們房到 OTA 更新軟體中的工具將根據系統的通訊協議提供的內容以及對安全性和可靠性的要求來確定。
解決安全挑戰
安全解決方案需要對通過空中傳送的新應用程式保密,檢測新應用程式中的任何損壞,並驗證新應用程式是從受信任的伺服器傳送的,而不是從惡意方傳送的。 這些挑戰可以通過使用加密(crypto)操作來解決。
具體來說,可以在安全解決方案中使用兩種稱為加密和雜湊的加密操作。 加密技術將在客戶端和伺服器之間使用一個共享的金鑰(密碼)來混淆無線傳輸的資料。 微控制器的密碼硬體加速器可能支援的一種特殊型別的加密被稱為 AES-128或 AES-256,這取決於金鑰的大小。 與加密的資料一起,伺服器可以傳送摘要,以確保沒有損壞。 這個摘要是通過雜湊資料包(一個生成唯一程式碼的不可逆數學函式)生成的。 如果訊息或摘要的任何部分在伺服器建立它們之後被修改,比如在無線通訊期間有一個位被翻轉,當客戶端對資料包執行相同的雜湊函式並比較摘要時,它會注意到這個修改。
微控制器的加密硬體加速器可能支援的一種特定型別雜湊方式是 SHA-256。 圖6顯示了微控制器中的加密硬體外設的框圖,OTA 更新軟體位於 Cortex-M4應用層。 此圖還顯示了對外圍裝置中的受保護金鑰儲存的支援,可以在 OTA 更新軟體解決方案中利用該支援來安全儲存客戶端的金鑰。
圖6 基於 ADuCM4050的密碼加速器硬體框圖
使用非對稱加密是解決身份驗證最後挑戰的一種常用技術。 對於此操作,伺服器生成一個公私金鑰對。只有伺服器知道私鑰,而客戶機知道公鑰。 使用私鑰,伺服器可以生成給定資料塊的簽名——就像將通過無線方式傳送的包的摘要一樣。 簽名被髮送到客戶端,客戶端可以使用公鑰驗證簽名。 這使客戶機能夠確認訊息是從伺服器發出的,而不是由流氓第三方發出的。 這個序列如圖7所示,用實箭頭表示函式的輸入 / 輸出,用虛箭頭表示通過空中傳送的資訊。
圖7 使用非對稱加密對訊息進行身份驗證
大多數微控制器沒有硬體加速器來實現這些非對稱加密操作,但可以使用諸如 Micro-ECC 等軟體庫來實現,這些軟體庫專門針對資源受限的裝置。庫需要一個使用者定義的隨機數母函式,這可以實現使用真隨機數發生器的硬體外圍的微控制器。
儘管這些非對稱加密操作解決了 OTA 更新過程中的信任問題,但它們在處理時間方面代價高昂,而且需要將簽名與資料一起傳送,這增加了資料包的大小。 可以在下載結束時執行一次檢查,使用最終包的摘要或整個新軟體應用程式的摘要,但這將允許第三方下載不受信任的軟體到客戶端,這並不理想。 理想情況下,希望驗證所收到的每個資料包都是來自受信任的伺服器,而且每次都不需要簽名的開銷。 這可以通過雜湊鏈來實現。
雜湊鏈將這裡討論的加密概念合併為一系列資料包,從而實現數學上的連線。 如圖8所示,第一個包(數字0)包含下一個包的摘要。 與實際的軟體應用程式資料不同,第一個資料包的負載是簽名。 第二個包(編號1)有效負載包含二進位制的一部分和第三個包的摘要(編號2)。 客戶端驗證第一個資料包中的簽名,並快取摘要 H0,以供以後使用。 當第二個資料包到達時,客戶端雜湊負載並將其與 H0進行比較。 如果它們匹配,客戶端可以確定這個後續資料包來自受信任的伺服器,而不需要進行簽名檢查。 生成這個鏈的代價高昂的任務留給了伺服器,當每個資料包到達時,客戶機必須簡單地快取和雜湊,以確保資料包到達時沒有損壞,具有完整性,並經過驗證。
圖8 將雜湊鏈應用於包序列
實驗驗證
本文中提到的解決儲存器、通訊和安全設計難題的超低功耗微控制器是 ADuCM3029和 ADuCM4050。 這些微控制器包含為 OTA 更新討論的硬體外設,如快閃記憶體、 SRAM、加密加速器和真正的隨機數發生器。 用於這些微控制器的裝置家族包(DFP)為在這些裝置上構建 OTA 更新解決方案提供軟體支援。 DFP包含外圍驅動程式,為硬體提供了簡單、靈活的介面。
硬體配置
為了驗證這裡討論的概念,使用 ADuCM4050建立了一個 OTA update 軟體參考設計。 對於客戶端,ADuCM4050 EZ-KIT 通過使用無線收發器連線到 ADF7242。 客戶機裝置如圖9所示。 對於伺服器,開發了一個在 Windows PC 上執行的 Python 應用程式。 Python 應用程式通過串列埠與另一個 ADuCM4050 EZ-KIT 進行通訊,後者也有 ADF7242與客戶端相同的設定。 然而,圖9中右邊的 EZ-KIT 不執行 OTA 更新邏輯,只是將從ADF7242收到的資料包轉發給 Python 應用程式。
圖9 實驗性硬體設定
軟體元件
如圖3所示的軟體參考設計對客戶端裝置的快閃記憶體進行分割槽。 主要的客戶端應用程式被設計為可移植和可配置的,這樣就可以在其他配置或其他硬體平臺上使用。 圖10顯示了客戶端裝置的軟體架構。請注意,雖然有時將整個應用程式稱為 SSBL,但是在圖10中以及從現在開始,從邏輯上將真正的 SSBL 部分(藍色)與 OTA 更新部分(紅色)分開,因為後者不一定需要像前面討論的那樣完全在同一個應用程式中實現。 圖10所示的硬體抽象層層保持了 OTA 客戶端軟體的可移植性,並且獨立於任何底層庫(如橙色所示)。
圖10 客戶端軟體體系架構
軟體應用程式實現了圖3中的引導序列,一個從伺服器下載新應用程式的簡單通訊協議,以及雜湊鏈。 通訊協議中的每個資料包都有12位元組的元資料頭、64位元組的有效負載和32位元組的摘要。此外,它還具有以下特點:
-
快取: 支援不快取或快取一頁快閃記憶體,具體取決於使用者配置。
-
目錄: ToC 被設計用於只儲存兩個應用程式,並且新的應用程式總是被下載到最老的位置,以保留一個回退應用程式。 這就是所謂的 A/B更新方案。
-
訊息傳遞: 根據使用者配置,對訊息傳遞的 ADF7242或 UART 提供支援。 使用 UART 進行訊息傳遞消除了圖9中左邊的 EZ-KIT,使得右邊的部分留給了客戶端。 這種線上更新方案對於初始化系統和除錯非常有用。
實驗結果
除了滿足功能需求和通過各種測試之外,軟體的效能也是決定專案成功與否的關鍵。 兩個通常用來衡量嵌入式軟體效能的指標是佔用空間和指令週期。 佔用空間是指軟體應用程式在SRAM和Flash中佔用的空間。 指令週期是指軟體用來執行特定任務的微處理器時鐘週期數。 雖然它類似於軟體執行時,但它解釋了這樣一個事實,即在進行 OTA 更新時,軟體可能會進入低功耗模式,因為在那裡微處理器是非活動的,並且沒有消耗週期。 雖然軟體參考設計沒有針對這兩個度量標準進行優化,但是它們對於測試程式和比較設計權衡都是有用的。
圖11和圖12顯示了 OTA 更新軟體參考設計在 ADuCM4050上實現的記憶體大小,不使用快取。 這些數字是根據圖10所示的元件進行分割槽的。 如圖11所示,整個應用程式使用約15kb 的快閃記憶體。 考慮到 ADuCM4050包含512kb 的快閃記憶體,這個資料太小了。 真正的應用軟體(為OTA更新過程開發的軟體)只需要1.5 kB 左右,其餘部分用於 DFP、 Micro-ECC 和 ADF7242堆疊等庫。 這些結果有助於說明 SSBL 在系統中應該扮演的角色的設計權衡。 大多數15 kB 的記憶體佔用用於更新過程。 SSBL本身只佔用大約500個位元組的記憶體空間,另外還有1到2 kB 的 DFP 程式碼用於裝置訪問,比如 Flash 驅動程式。
圖11 快閃記憶體佔用空間(位元組)
圖12 SRAM佔用空間(位元組)
為了評估軟體的開銷,在每次收到資料包時執行指令週期計數,然後檢視每個包所消耗的平均指令週期數。 每個資料包都需要 AES-128解密、 SHA-256雜湊、對快閃記憶體的寫入以及一些包的元資料驗證。 在資料包有效負載為64位元組且沒有快取的情況下,處理單個數據包的開銷為7409週期。 使用26Mhz時鐘,處理時間約為285微秒。 該值是使用位於 ADuCM4050 DFP (未調整週期)的迴圈計數驅動程式計算的,是100kb 二進位制下載(大約1500個數據包)期間的平均值。
每個包的最小開銷可歸因於 DFP 中的驅動程式在執行匯流排事務時利用 ADuCM4050上的直接記憶體訪問(DMA)硬體外設,以及驅動程式在每個事務期間將處理器置於低功耗睡眠狀態。 如果禁用 DFP 中的低功耗休眠,並將匯流排事務改為不使用 DMA,那麼每個資料包的開銷將增加到17,297個週期。 這說明了裝置驅動程式的有效使用對嵌入式軟體應用程式的影響。 雖然每個資料包的資料位元組數很少,因此開銷也很低,但是每個資料包的資料位元組數增加一倍,達到128,只會在迴圈中產生一個小的增長,因此對於同樣的實驗,需要8,362個指令週期。
指令週期和佔用空間還說明了前面討論的快取包資料而不是每次寫入快閃記憶體的權衡。 啟用一頁快閃記憶體快取後,每個資料包的開銷從7,409減少到5,904個週期。 這20% 的減少是由於對大多數包跳過了Flash 寫操作,並且只在快取滿的時候執行一次Flash 寫操作。 這種減少是以SRAM為代價的。 如果沒有快取,HAL只需要336個位元組的 SRAM,如圖12所示。 然而,當使用快取時,必須保留相當於一整頁快閃記憶體的空間,這將 SRAM 的利用率增加到2,388個位元組。 HAL 的快閃記憶體利用率也略有提高,因為需要額外的程式碼來決定什麼時候必須重新整理快取。
這些結果證明了設計決策對軟體效能的切實影響。 沒有放之四海而皆準的解決方案ーー每個系統都有不同的需求和限制,而且 OTA 的更新軟體需要進行調整以解決這些問題。 希望本文對設計、實現和驗證 OTA 更新軟體解決方案時遇到的一些常見問題和解決方案提供一些幫助,真正弄懂如何實現物聯網裝置的OTA。
參考資料:
Nilsson, Dennis Kengo and Ulf E. Larson. “Secure Firmware Updates over the Air in Intelligent Vehicles.” ICC Workshops—2008 IEEE International Conference on Communications Workshops, May 2008.
(本文 編譯自 http://www.embedded-computing.com/guest-blogs/over-the-air-ota-updates-in-embedded-microcontroller-applications-design-trade-offs-and-lessons-learned)