大家好,我是bug菌!最近一些朋友在玩在線升級(jí),所以這里bug菌挑選了一篇原理與實(shí)踐結(jié)合的技術(shù)文章,在stm32上實(shí)現(xiàn)還是比較詳細(xì)的,以前bug也跟大家介紹過(guò)這一塊的設(shè)計(jì)方案:【重磅】剖析MCU的
IAP升級(jí)軟件設(shè)計(jì)(設(shè)計(jì)思路篇)【MCU】一種"靈活且省資源"的
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ū)劃分, 到
代碼編寫(xiě)和
實(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程序的.
正常情況下, 我們寫(xiě)的程序都是放在STM32片內(nèi)Flash中(暫不考慮外擴(kuò)Flash). 我們寫(xiě)的代碼最終會(huì)變成二進(jìn)制文件, 放進(jìn)Flash中 感興趣的話可以在
Keil>>>
Debug>>>
Memory中查看, 右邊Memory窗口存儲(chǔ)的就是代碼接下來(lái)就可以進(jìn)入正題了.
進(jìn)行分區(qū)
既然我們寫(xiě)的程序都會(huì)變成二進(jìn)制文件存放到Flash中, 那么我們就可以進(jìn)一步對(duì)我們程序進(jìn)行分區(qū). 我使用的是
F103RB-NUCLEO開(kāi)發(fā)板,他的Flash一共128頁(yè), 每頁(yè)1K.見(jiàn)下圖:以它為例, 我將它分為三個(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的編寫(xiě)
本節(jié)主要講解在線升級(jí)(OTA)的
BooLoader的編寫(xiě),我將以我例程的BootLoader為例, 講解
BootLoader(文末會(huì)提供免費(fèi)的代碼下載鏈接),其他的大體上原理都差不多。
流程圖分析
以我例程的BootLoader為例:我將
App2區(qū)的最后一個(gè)字節(jié)(
0x0801FFFC)用來(lái)表示
App2區(qū)是否有升級(jí)程序, STM32在擦除之后Flash的數(shù)據(jù)存放的都是
0xFFFFFFFF, 如果有, 我們將這個(gè)地址存放
0xAAAAAAAA. 具體的流程圖見(jiàn)下圖所示
程序編寫(xiě)和分析
所需
STM32的資源有:
- 發(fā)送USART數(shù)據(jù)和printf重定向
- Flash的讀寫(xiě)
- 程序跳轉(zhuǎn)指令,可以參考如下代碼:
1/*?采用匯編設(shè)置棧的值?*/ 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;
1415??
if?(?(?(?*?(?__IO?uint32_t?*?)?App_Addr?)?