嵌入式固件升級框架詳解與實戰經驗
嵌入式固件升級(Firmware Update)是什么?
固件升級是指在設備不拆解、不更換芯片的前提下,為了修復Bug、增加新功能或提升性能,通過軟件方式更新嵌入式系統固件。
對嵌入式產品而言,固件升級機制可以保持產品生命周期期間的生命力。
單片機有三種燒錄方式:
- ICP(In Circuit Programing)在電路編程;
使用仿真器(如 J-Link、ST-Link)經 SWD/JTAG 接口進行編程,常用于開發調試階段或產線燒錄。
特點是可靠、快速,但是依賴仿真器,而正版仿真器的采購成本一般也較高。 - ISP(In System Programing)在系統編程;
芯片出廠前通常會自帶一小段ROM Bootloader,可通過 UART/SPI/I2C 等接口與上位機交互,實現系統內燒錄。
進入方式通常需拉高或拉低特定引腳。
特點是開發者無法修改ROM Bootloader邏輯,靈活性較差,燒錄速度也比不上ICP,ISP常用于量產燒錄或后期維護。
在某些調試場景下,比如上電后立即關閉SWD,會導致無法重新燒錄,芯片變磚,就需要該種方式作為最后的救命手段。調試建議:初始化中可加 1~2 秒延時,避免出現該極端場景。 - IAP(In applicating Programing)在應用編程;
本文所說的固件升級主要是基于 IAP(In-Application Programming)機制的實現。通過軟件在運行時實現 Flash 擦寫與編程。
程序通常分為兩部分:
- Bootloader(引導程序):負責通信、下載、校驗與切換;
- APP(應用程序):正常業務邏輯運行部分。
要實現 IAP,開發者需先考慮以下條件是否滿足: - 芯片是否具備通信接口(UART / SPI / I2C / BLE / Wi-Fi)
- ROM / RAM 空間是否充足
- ROM 是否支持在線擦寫
什么時候需要固件升級功能?
如果產品功能需要頻繁迭代更新或遠程維護,那么就需要在設計階段考慮固件升級,同時也要考慮硬件成本、研發成本和測試成本。
固件升級功能的使用者可分為三類:開發人員、維護人員和用戶。
如果只是開發調試階段需要更新軟件,可只做仿真器燒錄;如果需要長期維護產品,則應預留Bootloader;如果是聯網設備,則建議考慮OTA。
常見的升級方式

無論哪種方式,核心流程都是一致的:
跳轉 → 握手 → 下載 → 校驗 → 切換/回滾
升級流程詳解
以終端與PC上位機交互升級為例:
1.跳轉機制
進入Bootloader有兩種方式,一種是復位,每次復位先執行Bootloader;一種是從APP應用程序使用跳轉指令跳轉到Bootloader,這種需要設計一定的觸發條件,比如通過上位機指令等。
系統啟動后首先運行 Bootloader。Bootloader 決定:
- 是否進入升級模式;
- 還是直接跳轉到 APP。
判斷方法通常有兩種: - 超時等待:上電后在 1s 內未收到升級信號則跳轉 APP;簡單但影響開機速度;
- 升級標志位:上位機設置標志位,Bootloader 檢查后進入升級模式。
推薦做法:標志位 + 校驗結合,可提升升級可靠性。
![image]()
2.握手階段
升級前,終端需與上位機確認狀態和版本信息,例如:
上位機:準備就緒?------------------------------------------------------終端:準備就緒
終端:當前我是v1.0版本,你是什么版本?------------------------上位機:我是v1.2版本
終端:請求升級至1.2版本,固件信息?-----------------------------上位機:固件名、固件大小、校驗值
這一過程稱為握手(Handshake),主要目的是:
- 確認通信正常;
- 校驗版本信息;
- 確定升級包信息。
3.下載階段
握手完成后開始傳輸固件數據。
一般為分包下載:
終端:請發送第0包固件數據------------------------上位機:第0包數據
......
終端:請發送第Z包固件數據------------------------上位機:第Z包數據
接收數據,還需要將固件數據寫入flash,需要選擇升級策略:


模式特點單Bank占用空間少,但失敗可能“變磚”雙Bank安全可靠,支持回滾,但占用Flash更大
RAM建議:至少預留 2~3 倍單包大小的緩沖區,因為要在 RAM 中緩存接收數據、進行校驗和 Flash 對齊寫入,若包太大或 RAM 太小會影響速度與可靠性。
若下載過程同時保存當前包序號到flash,那么當系統掉電或通信中斷,可通過該包序號實現斷點續傳;同時,在 Bootloader 啟動階段檢測該標志,可自動恢復下載流程或清除異常狀態,提高升級效率。
4.校驗階段
固件接收完成后進行完整性校驗。
常用校驗方法有CRC或者SHA校驗,對于 MCU 通信型升級(UART、SPI等),CRC足夠;對于 OTA 或安全性較高場景,建議 SHA + 簽名機制。。
調試建議:寫入完畢后從Flash回讀再校驗,避免邊寫邊算導致誤差。
5.切換與回滾
校驗成功后,Bootloader將更新固件有效標志位,并在下次重啟時跳轉到新APP。
啟動失敗(如CRC錯誤或啟動異常)時,若支持回滾機制(Rollback)則自動回退到上個版本,否則就滯留在Bootloader,等待下一次升級開始:
關于Bootloader和APP之間相互跳轉,有幾個注意事項:
跳轉時應先關閉中斷、重設堆棧指針(MSP)、并跳轉至 APP 的 Reset_Handler,否則可能導致啟動異常。
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;
void IAP_JumpToApplication(void)
{
__disable_irq(); //關閉中斷
JumpAddress = *(__IO uint32_t*) (APP_ADDRESS + 4);//獲取Reset_Handler指針
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) APP_ADDRESS); //從設堆棧指針
JumpToApplication(); //跳轉
}
在Bootloader中會用到某些外設,如看門狗、UART、定時器等,跳轉到APP后,這些外設可能還會繼續工作,進而影響產品功耗或者外設配置沖突,建議在跳轉前可增加反初始化。
安全性設計要求
在OTA場景,固件升級必須考慮安全問題:
- 簽名驗證,要確保固件來源可信
- 加密傳輸,避免固件在空中被截獲
- 版本防降級,防止回刷舊固件,利用舊固件版本漏洞攻擊
- 校驗完整性,防止傳輸過程損壞、錯漏
擴展
嵌入式產品由于資源限制和應用場景不同,有時候不會固定Bootloader+APP、單雙Bank這些選擇。會有許多變種設計,咱們在此適當展開說說。
1.單Bank+差分升級

上位機不直接發送整包固件,而是發送舊版本與新版本的差異數據,設備端根據當前固件內容和補丁生成新固件。
該方案的Flash 占用居于單bank和雙bank之間,帶寬和功耗最低,升級速度最快,但實現復雜度也是最高的。
優點:
- Flash 占用居于單Bank和雙Bank之間(多出一塊Patch區);
- 帶寬占用最低,適合 BLE / LoRa / NB-IoT 等低速物聯網設備;
- 升級速度快、功耗低;
缺點: - 實現復雜度高,需保證差分算法與舊固件一致;
- 無法像雙Bank支持回滾;
- 如果掉電或Patch損壞仍有變磚風險。
2.雙bootloader

前面我們使用bootloader給APP升級,那要是bootloader也需要升級呢?
在一些高可靠性或多階段升級場景中,會使用兩個 Bootloader:主Bootloader 和 子Bootloader。
正常情況下,主Bootloader 負責設備啟動與APP升級,當主Bootloader需要升級或者被破壞時,子Bootloader進行接管。
優點:
- 解決“Bootloader自身無法自升級”的問題;
- 增加了安全性,避免主Bootloader損壞后系統無法啟動問題;
缺點: - 增加Flash占用(雙Bootloader本身需要空間);
- 啟動流程、跳轉流程更加復雜,調試門檻高;
3.RAM運行bootloader
這種方式同樣也可以解決bootloader的問題。
把Bootloader 加載到 RAM 中運行,從而可以自由擦寫整個 Flash(包括自身所在區域)。
優點:
- 允許完全自由地重寫Flash布局(包括Bootloader區);
- Flash利用率高,可實現Bootloader自升級而不需雙Bootloader設計,適合Flash緊張的系統;
缺點: - RAM 需足夠大以容納Bootloader;
- 一旦RAM運行異常(如掉電),可能導致系統不可啟動,比前面提及的變磚更加嚴重;
總結
嵌入式固件升級是一個看似簡單,但實現難度較大的功能,對可靠性、安全性、成本控制、性能、系統架構設計都有著嚴格的要求。


浙公網安備 33010602011771號