詳解STM32在線IAP升級(jí)
當(dāng)然目前比較火熱的OTA升級(jí),為了保證升級(jí)過(guò)程的權(quán)限、完整性、穩(wěn)定性等等,還需要做很多工作包括加密、壓縮等等,可能會(huì)更加復(fù)雜一點(diǎn),特別是差分升級(jí),通過(guò)版本之間的差異來(lái)生成升級(jí)包進(jìn)行升級(jí),一方面可以節(jié)省空間,另一方面也能夠加快升級(jí)速度,這一塊bug菌后續(xù)整理一下~好了,下面這篇文章,大家好好學(xué)習(xí)一下:
簡(jiǎn)介
本文主要講解在線升級(jí)IAP的基礎(chǔ)知識(shí), 主要是針對(duì)IAP?
從原理分析
,?分區(qū)劃分
, 到代碼編寫
和實(shí)驗(yàn)驗(yàn)證
等過(guò)程闡述這一過(guò)程. 幫助大家加深對(duì)在線升級(jí)的認(rèn)識(shí).1. 在線升級(jí)知識(shí)
什么是BootLoader?
BootLoader
可以理解成是引導(dǎo)程序, 它的作用是啟動(dòng)正式的App應(yīng)用程序
. 換言之,?BootLoader
是一個(gè)程序, App也是一個(gè)程序, ?BootLoader程序
是用于啟動(dòng)App程序
的.STM32中的程序在哪兒?
正常情況下, 我們寫的程序都是放在STM32片內(nèi)Flash中(暫不考慮外擴(kuò)Flash). 我們寫的代碼最終會(huì)變成二進(jìn)制文件, 放進(jìn)Flash中 感興趣的話可以在Keil
>>>Debug
>>>Memory
中查看, 右邊Memory窗口存儲(chǔ)的就是代碼接下來(lái)就可以進(jìn)入正題了.進(jìn)行分區(qū)
既然我們寫的程序都會(huì)變成二進(jìn)制文件存放到Flash中, 那么我們就可以進(jìn)一步對(duì)我們程序進(jìn)行分區(qū). 我使用的是F103RB-NUCLEO開發(fā)板
,他的Flash一共128頁(yè), 每頁(yè)1K.見下圖:以它為例, 我將它分為三個(gè)區(qū).BootLoader區(qū)
、?App1區(qū)
、?App2區(qū)(備份區(qū))
具體劃分如下圖:BootLoader區(qū)
存放啟動(dòng)代碼App1區(qū)
存放應(yīng)用代碼App2區(qū)
存放暫存的升級(jí)代碼
總體流程圖
- 先執(zhí)行
BootLoader
程序, 先去檢查APP2
區(qū)有沒(méi)有程序, 如果有就將App2區(qū)(備份區(qū))的程序拷貝到App1區(qū)
, 然后再跳轉(zhuǎn)去執(zhí)行App1
的程序. - 然后執(zhí)行
App1
程序, 因?yàn)?code style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">BootLoader和App1
這兩個(gè)程序的向量表不一樣, 所以跳轉(zhuǎn)到App1
之后第一步是先去更改程序的向量表. 然后再去執(zhí)行其他的應(yīng)用程序. - 在應(yīng)用程序里面會(huì)加入程序升級(jí)的部分, 這部分主要工作是拿到升級(jí)程序, 然后將他們放到
App2區(qū)(備份區(qū))
, 以便下次啟動(dòng)的時(shí)候通過(guò)BootLoader
更新App1
的程序. 流程圖如下圖所示:
2. BootLoader的編寫
本節(jié)主要講解在線升級(jí)(OTA)的BooLoader
的編寫,我將以我例程的BootLoader為例, 講解BootLoader
(文末會(huì)提供免費(fèi)的代碼下載鏈接),其他的大體上原理都差不多。流程圖分析
以我例程的BootLoader為例:我將App2區(qū)
的最后一個(gè)字節(jié)(0x0801FFFC
)用來(lái)表示App2區(qū)
是否有升級(jí)程序, STM32在擦除之后Flash的數(shù)據(jù)存放的都是0xFFFFFFFF
, 如果有, 我們將這個(gè)地址存放0xAAAAAAAA
. 具體的流程圖見下圖所示程序編寫和分析
所需STM32的資源有:- 發(fā)送USART數(shù)據(jù)和printf重定向
- Flash的讀寫
- 程序跳轉(zhuǎn)指令,可以參考如下代碼:
2__asm?void?MSR_MSP?(uint32_t?ulAddr)
3{
4????MSR?MSP,?r0???//設(shè)置Main?Stack的值
5????BX?r14
6}
7
8
9/*?程序跳轉(zhuǎn)函數(shù)?*/
10typedef?void?(*Jump_Fun)(void);
11void?IAP_ExecuteApp?(uint32_t?App_Addr)
12{
13??Jump_Fun?JumpToApp;
14
15??if?(?(?(?*?(?__IO?uint32_t?*?)?App_Addr?)?