STM32通過USB實現(xiàn)Bootloader/IAP功能
前沿:
最近在做STM32的USB Bootlader/IAP功能,也就是通過USB實現(xiàn)固件升級,本文介紹下實現(xiàn)的基本思路,希望對實現(xiàn)IAP的同學一個參考,改方法已經(jīng)在產(chǎn)品中得到實際應(yīng)用并驗證是比較合理,穩(wěn)定可靠的。
程序空間劃分:
在單片機的程序Flash中分兩個區(qū),分別存儲Bootloader代碼和App代碼,Bootloader放到代碼起始地址,也就是0x08000000,App放到0x8020000地址,中間預(yù)留了很多的地址空間,主要是為了用來存儲一些需要掉電保存的數(shù)據(jù),比如我在0x0800C000地址就存放了App程序運行后寫入該地址的標志數(shù)據(jù)。
啟動流程:
上電后自然是運行Bootloader程序,Bootloader運行后,做的第一件事情如下所示
01
02
03
if((*((uint32_t*)EXE_FLAG_ADDR))==0x12345678){
JumpToApplication(APP_START_ADDR);
}
也就是判斷App運行標志是否有效,這個標志是存放到EXE_FLAG_ADDR地址的,若有效就直接跳轉(zhuǎn)到App程序運行,這個時間很短,所以用戶看不到有Bootloader執(zhí)行的效果,感覺就是直接運行的App程序,進入App程序后,App程序第一件事情如下
01
02
03
04
05
06
07
if((*((uint32_t*)EXE_FLAG_ADDR))==0xFFFFFFFF){
uint32_tExeFlag = 0x12345678;
__set_PRIMASK(1);//禁止全局中斷
FLASH_Unlock();
ProgramDatatoFlash(EXE_FLAG_ADDR,(uint8_t*)(&ExeFlag),4);
FLASH_Lock();
}
也就是判斷App標志是否有效,若有效則直接執(zhí)行后面的程序,若無效則需要在EXE_FLAG_ADDR地址寫入執(zhí)行標志。
Bootloader程序判斷App標志若無效,那么Bootloader就不會直接跳轉(zhuǎn)到App,因為這個時候是需要進行升級App的操作,所以程序就進入Bootloader的正常工作流程,也就是等待升級App的各種命令,比如擦出固件,燒寫固件,校驗固件等。當固件成功寫入并校驗通過之后,PC端就可以發(fā)送一個程序跳轉(zhuǎn)命令跳轉(zhuǎn)到App執(zhí)行。
PC端操作流程:
PC端和單片機是通過USB進行數(shù)據(jù)交換的,當然用其他方式也可以,基本流程都是差不多的。
PC程序首先當然是掃描設(shè)備,打開設(shè)備,然后調(diào)用獲取固件信息的函數(shù),調(diào)用該函數(shù)后可以得知當前固件的名稱,版本號,固件類型(Bootloader還是App),若發(fā)現(xiàn)當前固件不是Bootloader,那么就得通過USB給固件發(fā)送一個程序跳轉(zhuǎn)命令,也就是跳轉(zhuǎn)到Bootloader代碼執(zhí)行,當然App在跳轉(zhuǎn)到Bootloader的時候必須把EXE_FLAG_ADDR地址的標志數(shù)據(jù)擦出掉,這樣Bootloader才能進入正常的升級流程。
控制固件程序進入Bootloader之后,PC端程序?qū)⒋蜷_App固件程序文件,然后根據(jù)文件大小,發(fā)送擦出App代碼存儲區(qū)域Flash的數(shù)據(jù),然后再分包將固件發(fā)送給單片機,單片機端Bootlader程序接收到數(shù)據(jù)后將數(shù)據(jù)寫入App的Flash區(qū)域,數(shù)據(jù)寫完之后再進行校驗,我是通過計算CRC16的方式進行校驗的,校驗通過之后就可以發(fā)送跳轉(zhuǎn)命令控制程序跳轉(zhuǎn)到App運行了,到此升級流程完畢。