STM32 OTA-IAP設計方案
OTA是Over-the-Air的簡寫,即空中下載下傳技術,通過網絡遠端給使用者進行系統更新和更新。IAP是In Application Programming的簡寫,IAP是使用者自己的程式在運作過程中對User Flash的部分區域進行燒寫,目的是為了在産品釋出後可以友善地通過預留的通信口對産品中的固件程式進行更新更新。IAP主要包括BootLoader和應用程式兩部分,基于IAP的OTA設計思路是先通過OTA接收更新固件,再利用IAP進行固件搬移、校驗和程式跳轉,實作空中更新的目的。
BootLoader程式根據判斷是否需要更新固件,并進行運作代碼跳轉。APP工程中需要編寫OTA資料包互動協定,将接收到的更新固件儲存至FLASH,校驗一緻性然後設定更新标志位并重新開機。
一、STM32啟動模式分析
Cortex-M3 核心啟動有3種情況:
- 通過boot引腳設定可以将中斷向量表定位于SRAM區,即起始位址為0x2000000,同時複位後 PC 指針位于0x2000000處。
- 通過boot引腳設定可以将中斷向量表定位于FLASH區,即起始位址為0x8000000,同時複位後PC指針位于0x8000000處。
- 通過boot引腳設定可以将中斷向量表定位于内置Bootloader區。
Cortex-M3核心規定,起始位址必須存放棧頂指針,而第二個位址則必須存放複位中斷入口向量位址,在Cortex-M3核心複位後,會自動從起始位址的下一個32位空間取出複位中斷入口向量,跳轉執行複位中斷服務程式。Boot引腳設定見下表。
BOOT0 | BOOT1 | 啟動模式 |
---|---|---|
無關 | FLASH | |
1 | 系統存儲器,ISP模式 | |
1 | 1 | SRAM,調試 |
STM32的啟動檔案(startup_stm32f103xb.s)和啟動過程。
(1)首先對棧和堆的大小進行定義,并在代碼區的起始處建立中斷向量表,其第一個表項是棧頂位址(32位),第二個表項是複位中斷服務入口位址;
(2)然後執行複位中斷,在複位中斷服務程式中跳轉 C/C++标準實時庫的main函數(__main),完成使用者堆棧等的初始化後,跳轉.c 檔案中的main函數(真正的使用者main函數)開始執行程式。
假設STM32被設定為從内部FLASH啟動,中斷向量表起始地位為0x8000000,則棧頂位址存放于0x8000000處,複位中斷服務入口位址存放于0x8000004處。當STM32遇到複位信号後,則從0x80000004處取出複位中斷服務入口位址,繼而執行複位中斷服務程式,然後跳轉__main函數,最後進入main函數。
二、FLASH分區
設定STM32為從FLASH啟動,即硬體設定管腳BOOT0低電平。本方案單片機型号采用:STM32F103RBT6,FLASH:128KB, SRAM:20KB。FLASH分為Bootloader、APPA、APPB、Parameter4個部分,分别占用20kB、50kB、50kB和8kB記憶體空間。APPA是應用程式區,運作使用者設計的應用程式;APPB是應用程式備份更新區,存放接收到的固件更新包;Parameter是參數區,儲存程式運作的關鍵參數、更新标志和密鑰。FLASH分區示意圖如下圖所示。

三、OTA流程
單片機上電後首選運作BootLoader該段代碼,讀取Parameter參數區的更新标志量,判斷是否有更新需求。若有更新需求,則根據記錄的相應固件大小将APPB區更新檔案拷貝至APPA區,并改寫更新标志量,然後重新開機;若無更新請求,則程式跳轉至APPA代碼區運作。OTA程式流程如下所示。
具體流程描述如下:
Step1:上電啟動單片機,首先執行BootLoader程式。
Step2:BootLoader讀取Parameter區參數,檢視更新标志是否有更新任務,若沒有更新任務,則進入 Step3,否則進入 Step4。
Step3: BootLoader程式跳轉至APPA,執行使用者代碼,并判斷是否收到更新任務請求,若有更新任務請求則進入 Step7。
Step4:根據Parameter區更新參數,校驗APPB固件資料并将APPB更新固件拷貝到APPA區,執行 Step5 和 Step6。
Step5:将更新标志位清除。
Step6:重新開機,再次執行BootLoader。
Step7:将接受到的更新資料包存入APPB區,并将相關更新參數存入Parameter區,若接收資料完成,固件檢驗通過則寫入Parameter區更新标志,并進入 Step8 。
Step8:重新開機,再次執行BootLoader。
四、工程設定
4.1 BootLoader工程設定
由于BootLoader需要在上電複位後首先執行,是以,設定BootLoader存放在FLASH起始位置0x08000000,在MDK中打開options for target,設定IROM1 Start = 0x08000000,Size = 0x5000(0x5000 = 20kB),在Flash Download中設定下載下傳Flash位置,參數與IROM1中設定Start和Size相同。BootLoader代碼大小不超過20kB,越小越好。
4.2 APP工程設定
根據FLASH分區,APP代碼存放在緊挨着BootLoader之後,是以APP的起始位置應該為0x08000000+0x5000 = 0x08005000,占用記憶體大小為0xC800(50kB),在MDK中打開options for target,設定IROM1 Start = 0x08005000,Size = 0xC800,在Flash Download中設定下載下傳Flash位置,參數與IROM1中設定的Start和Size相同,如圖5和圖6所示。由于APP代碼運作的起始位置不在0x08000000,其棧頂位址發生偏移,對應的中斷向量表位址也整體發生偏移,是以,在代碼中需要對APP代碼的中斷向量表偏移進行設定,具體的在system_stm32f1xxx.c中啟動代碼中可以看到定義的中斷向量表偏移量宏定義:
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x5000 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
更新界面如下:
裝置啟動界面如下:
下一篇準備寫個具體實作,包括本文提到的整包更新和朋友提到的差分更新,并且附帶配套的QT開發的更新軟體開發教程,考慮收費欄目。
有需求的朋友請私信,我統計一下情況。