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