找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 31408|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

STM32的BootLoader 從SD卡更新固件

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:75263 發(fā)表于 2015-6-9 03:29 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

1. 前言
2. 初識(shí)BootLoader
2.1     百度百科的BootLoader
2.2     BootLoader的簡(jiǎn)單理解
2.3     BootLoader的作用
3. BootLoader預(yù)備知識(shí)
3.1     復(fù)位序列
3.1.1      棧指針
3.1.2      復(fù)位向量
3.2     重定位中斷向量表
3.2.1      STM32的中斷向量表
3.2.2      設(shè)置中斷向量表偏移
3.3     分散加載文件相關(guān)
3.3.1      C語(yǔ)言的函數(shù)地址
3.3.2      BootLoader占用的ROM
3.3.3      修改ROM起始地址
3.4     hex文件和bin文件
3.4.1      hex文件
3.4.2      bin文件
3.5     Bin文件生成
4. 分幾步實(shí)現(xiàn)BootLoader
4.1     FAT文件系統(tǒng)
4.2     讀寫Flash程序
4.2.1      Flash寫入步驟
4.2.2      讀寫Flash調(diào)用的庫(kù)函數(shù)
4.2.3      實(shí)現(xiàn)Flash讀寫
4.3     跳轉(zhuǎn)到新程序運(yùn)行
4.3.1      跳轉(zhuǎn)到復(fù)位向量
4.3.2      App開始運(yùn)行
5. Bootloader具體流程
5.1     主函數(shù)流程
5.2     BootLoader流程
5.3     跳轉(zhuǎn)到新程序流程
附錄A主函數(shù)
附錄B更新說(shuō)明
參考文獻(xiàn)


1. 前言自從幾個(gè)月前接觸到有Bootloader這回事,就有一種強(qiáng)烈的沖動(dòng),想寫一個(gè)BootLoader出來(lái)。很快在飛思卡爾的Cortex-M4單片機(jī)上實(shí)現(xiàn),已經(jīng)是好幾個(gè)月前的事情了。然后關(guān)于BootLoader的事擱在一邊好久了,這次弄個(gè)STM32BootLoader出來(lái),Cortex-M3的,順便發(fā)表下博客,跟大家分享一下。
。。。
又過(guò)了大半年了吧,慢慢對(duì)BootLoader的認(rèn)識(shí)也有點(diǎn)長(zhǎng)進(jìn)啦。特別是跟網(wǎng)友討論后發(fā)現(xiàn)BootLoader的實(shí)現(xiàn)還是需要靠BootLoader程序和App程序的配合才能正常使用。在這里特別感謝網(wǎng)友cary_yingj ,對(duì)本BootLoader的研究后發(fā)現(xiàn)App程序需要重定位中斷向量表,才能正常工作。
在其他網(wǎng)友的反饋下,本人準(zhǔn)備再將次文檔完善,把不夠詳細(xì)的地方寫得再詳細(xì),并且力求通俗易懂一點(diǎn)。希望對(duì)學(xué)習(xí)BootLoader的同學(xué)們有所幫助。


2. 初識(shí)BootLoader可能有的同學(xué)聽說(shuō)過(guò)BootLoader,有的同學(xué)沒有聽說(shuō)過(guò),這個(gè)都很正常。關(guān)于BootLoader的概念大家可以上網(wǎng)查一下,有比較詳細(xì)的說(shuō)明,我在這里說(shuō)說(shuō)我自己比較片面的理解,并且是針對(duì)CortexM3說(shuō)明的,實(shí)現(xiàn)平臺(tái)為STM32F103VET6。
2.1       百度百科的BootLoader這里借用一下百度百科對(duì)BootLoader的解釋。在嵌入式操作系統(tǒng)中,BootLoader是在操作系統(tǒng)內(nèi)核運(yùn)行之前運(yùn)行?梢猿跏蓟布O(shè)備、建立內(nèi)存空間映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個(gè)合適狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。在嵌入式系統(tǒng)中,通常并沒有像BIOS那樣的固件程序(注,有的嵌入式CPU也會(huì)內(nèi)嵌一段短小的啟動(dòng)程序),因此整個(gè)系統(tǒng)的加載啟動(dòng)任務(wù)就完全由BootLoader來(lái)完成。在一個(gè)基于ARM7TDMIcore的嵌入式系統(tǒng)中,系統(tǒng)在上電或復(fù)位時(shí)通常都從地址0x00000000處開始執(zhí)行,而在這個(gè)地址處安排的通常就是系統(tǒng)的BootLoader程序。
2.2       BootLoader的簡(jiǎn)單理解BootLoader就是單片機(jī)啟動(dòng)時(shí)候運(yùn)行的一段小程序,這段程序負(fù)責(zé)單片機(jī)固件更新,也就是單片機(jī)選擇性的自己給自己下程序?梢愿乱部梢圆桓拢碌脑,BootLoader更新完程序后,跳轉(zhuǎn)到新程序運(yùn)行;不更新的話,BootLoader直接跳轉(zhuǎn)到原來(lái)的程序去運(yùn)行。
  需要注意的是:BootLoader下載新程序后并不擦除自己(BootLoader程序還在),下次啟動(dòng)依然先運(yùn)行BootLoader程序,又可以選擇性的更新或者不更新程序,所以BootLoader就是用來(lái)管理單片機(jī)程序的更新。
  這是本人的大概理解,大家有不明白請(qǐng)網(wǎng)上搜索一下更詳細(xì)介紹吧。
2.3       BootLoader的作用BootLoader使單片機(jī)能自己給自己下載程序,所以在程序升級(jí)方面非常有作用。比如我們的BootLoader是通過(guò)GSM更新程序的,我們?cè)谏?jí)單片機(jī)程序的時(shí)候,只要把新程序通過(guò)GSM發(fā)送給單片機(jī),單片機(jī)自己實(shí)現(xiàn)程序更新,然后跳轉(zhuǎn)到新程序執(zhí)行,這樣就省去我們很多升級(jí)的功夫啦。
可以想象一下如果把單片機(jī)安裝在非常高的地方,或者危險(xiǎn)的工業(yè)現(xiàn)場(chǎng),或者封裝得很難拆下來(lái),我們很難直接給單片機(jī)下載程序,那么BootLoader的作用就體現(xiàn)出來(lái)了。簡(jiǎn)單的說(shuō),有了BootLoader,我們更新程序的話是省心又省力。
想想是不是很高級(jí),還帶點(diǎn)小興奮哈哈。不用急,下面我們會(huì)繼續(xù)介紹,讓大家都能自己實(shí)現(xiàn)BootLoader。至于是通過(guò)什么方式升級(jí),這個(gè)大家自由發(fā)揮,相信會(huì)設(shè)計(jì)出豐富多彩的BootLoader升級(jí)方式呢。


3.BootLoader預(yù)備知識(shí)我們這里是為ARMCortex-M3單片機(jī)寫的BootLoader,需要了解一下M3內(nèi)核的架構(gòu),并且要了解M3單片機(jī)是怎么啟動(dòng)的等等。這個(gè)方面的知識(shí),可以參考《Cortex-M3權(quán)威指南》,這里的話我只是為了實(shí)現(xiàn)BootLoader簡(jiǎn)單介紹一下,大家有什么不清楚的請(qǐng)參考權(quán)威指南。并且這里是以STM32為例說(shuō)明問(wèn)題的,使用的開發(fā)環(huán)境是RVMDKKeil)。
3.1       復(fù)位序列這里參考的是《Cortex-M3權(quán)威指南》的3.8節(jié),復(fù)位序列。
M3單片機(jī)復(fù)位后,從0x00000000取棧指針(SP),0x00000004取復(fù)位向量(PC),有了棧指針和復(fù)位向量后,單片機(jī)就按照正常流程運(yùn)行了,在BootLoader里面,我們更新完程序后需要做的步驟之一就是設(shè)置棧指針,跳轉(zhuǎn)到復(fù)位向量。
3.1.1   棧指針棧是一種數(shù)據(jù)結(jié)構(gòu),后進(jìn)先出LIFO。借用百度百科的解釋:棧由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。它使用的是一級(jí)緩存,他們通常都是被調(diào)用時(shí)處于存儲(chǔ)空間中,調(diào)用完畢立即釋放。
3.1.2   復(fù)位向量復(fù)位向量是一個(gè)函數(shù)地址,在CortexM3單片機(jī)里是復(fù)位函數(shù)的地址。也就是單片機(jī)啟動(dòng)后第一個(gè)執(zhí)行的函數(shù)。
3.2       重定位中斷向量表這里參考《Cortex-M3權(quán)威指南》的7.3節(jié),向量表。
BootLoader是一個(gè)完整的程序,下載的新程序(以下稱為App)也是一個(gè)完整的程序。都包含中斷向量表,所以的話,我們是有兩個(gè)中斷向量表,相信因?yàn)橛袃蓚(gè)向量表,大家都知道我們應(yīng)該需要對(duì)這兩個(gè)向量表做點(diǎn)什么吧。
3.2.1   STM32的中斷向量表我們只看前16個(gè)向量,因?yàn)槠溆嗟南蛄繉儆谕庠O(shè)使用,與CortexM3內(nèi)核無(wú)關(guān)。
__Vectors      DCD    __initial_spTop          ;Top of Stack
               DCD    Reset_Handler            ; Reset Handler
               DCD    NMI_Handler              ; NMI Handler
               DCD    HardFault_Handler        ; Hard Fault Handler
               DCD    MemManage_Handler        ; MPU Fault Handler
               DCD    BusFault_Handler         ; Bus Fault Handler
               DCD    UsageFault_Handler       ; Usage Fault Handler
               DCD    0                        ; Reserved
               DCD    0                        ; Reserved
               DCD    0                        ; Reserved
               DCD    0                        ; Reserved
               DCD    SVC_Handler              ; SVCall Handler
               DCD    DebugMon_Handler         ; Debug Monitor Handler
               DCD    0                        ; Reserved
               DCD    PendSV_Handler           ; PendSV Handler
               DCD    SysTick_Handler          ; SysTick Handler
__initial_spTop就是棧指針,Reset_Handler是復(fù)位向量。這里只顯示了16個(gè)向量,CortexM3單片機(jī)的話總共有256個(gè)向量,也就是從棧指針的地址開始有1KB的區(qū)域?qū)儆谥袛嘞蛄勘怼?/div>單片機(jī)啟動(dòng)默認(rèn)先運(yùn)行BootLoader,所以默認(rèn)的中斷向量表位置是BootLoader的中斷向量表。為了App可以正常運(yùn)行,下載完App后,我們還需要把中斷向量表重新定位到App程序那里。根據(jù)《CortexM3權(quán)威指南》,介紹一下怎樣重定位中斷向量表。
3.2.2   設(shè)置中斷向量表偏移Cortex-M3單片機(jī)有一個(gè)管理中斷向量表的寄存器,叫做向量表偏移量寄存器(VTOR)地址0xE000_ED08。具體可以看看截圖:
STM332程序的起始地址一般在0x08000000。所以BootLoader程序是在0x08000000,不是在0x00000000是因?yàn)?/font>STM32的重映射技術(shù)(不符合Cortex-M3的設(shè)計(jì),有點(diǎn)搞另類的感覺)。所以BootLoader的中斷向量表在0x08000000那里。如果我們的App程序起始地址在0x08070000,并且App的中斷向量表在起始地址,那么BootLoader程序下載App后,為了App程序能正確運(yùn)行,開始App程序的運(yùn)行后第一步,就要把中斷向量表重定位到0x08070000那里。
具體實(shí)現(xiàn)下面會(huì)再介紹,接下來(lái)介紹分散加載文件相關(guān)內(nèi)容。
3.3       分散加載文件相關(guān)這一節(jié)涉及的內(nèi)容主要屬于分散加載文件,大家具體上網(wǎng)了解,這里只是介紹了能夠?qū)崿F(xiàn)BootLoader的一小部分。
3.3.1   C語(yǔ)言的函數(shù)地址我們知道C語(yǔ)言的函數(shù)名就是函數(shù)的地址,并且STM32單片機(jī)ROM的起始地址是在0x08000000,那么使用編譯器編譯程序的話(這里使用的是RVMDK),函數(shù)的地址默認(rèn)都在以0x08000000為首的一段ROM里面了。比如我們一個(gè)函數(shù)Delay(),它的地址可以是0x08000167CortexM3中函數(shù)的地址0bit位一般是1),也就是Delay函數(shù)的代碼在0x08000167,C語(yǔ)言函數(shù)調(diào)用Delay時(shí),就是執(zhí)行0x08000167的代碼。
3.3.2   BootLoader占用的ROM我們需要注意的問(wèn)題是,如果不修改程序默認(rèn)的起始地址的話,那么BootLoader和新App程序的起始地址都是0x08000000,也就是他們重疊了(代碼重疊),這樣的話肯定相互之間有影響,程序是不能正常工作的。
這里的解決方法是,BootLoader程序依然占用0x08000000為首的那段ROM,因?yàn)?/font>STM32的默認(rèn)就是從0x08000000運(yùn)行程序的。保持BootLoader程序先能正確運(yùn)行。然后App使用除BootLoader占用ROM以外的空間。這里需要知道BootLoader到底占用了多少ROM,很簡(jiǎn)單,查看MAP文件就行了。這里以我的BootLoaderMAP文件為例說(shuō)明一下,看截圖:
Memory Map of the image
  Image Entry point :0x08000131
  Load Region LR_IROM1 (Base: 0x08000000,Size: 0x00006da4, Max: 0x00080000, ABSOLUTE)
   Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00006d54, Max:0x00080000, ABSOLUTE)
主要是這句話“Base:0x08000000, Size: 0x00006da4, Max: 0x00080000,這句話說(shuō)明了我的BootLoader程序是從0x08000000開始,占用了0x00006DA4大小。只要我們的App不要和BootLoader程序占用的空間沖突就可以了。我的App程序的起始地址選擇為0x08070000,不與BootLoader程序沖突。具體怎么修改ROM起始地址,下面介紹。
3.3.3   修改ROM起始地址編譯新程序的時(shí)候,我們要修改程序的起始地址,我的修改方法如下(開發(fā)環(huán)境是RVMDK):打開TargetOption...,切換到Target選項(xiàng)卡,如下
修改IROM1的起始地址和長(zhǎng)度:
比如,為了不產(chǎn)生地址沖突,我將起始地址0x08000000修改成0x0807000,將ROM長(zhǎng)度0x80000修改成0x10000。如下圖所示(左圖為修改前、右圖為修改后):
  
注意:BootLoader程序是不需要修改的,只是App需要修改(App就是使用BootLoader下載的程序)。
3.4       hex文件和bin文件3.4.1   hex文件平時(shí)我們用j-Link或者串口下載程序的話,都是打開hex文件下載的,因?yàn)?/font>hex文件包含地址信息,下載程序的時(shí)候知道程序下載到ROM的哪個(gè)區(qū)域。從另一個(gè)角度上說(shuō),也就是hex文件是不能直接寫進(jìn)ROM的,一邊寫需要一邊轉(zhuǎn)換(解碼出地址信息,將對(duì)應(yīng)內(nèi)容寫入ROM)。
3.4.2   bin文件bin文件的話,很好理解,是直接的可執(zhí)行代碼。也就是bin文件的內(nèi)容跟下載ROM里面的內(nèi)容是一樣的。bin文件是沒有包含地址信息的,所以在下載之前要知道bin文件是要下載到ROM的那個(gè)區(qū)域。
我們的BootLoader下載的是bin文件,直接寫進(jìn)STM32Flash里面,地址信息的話就是上一節(jié)的IROM,0x08070000,從0x08070000開始連續(xù)寫入,中間不間斷。
3.5       Bin文件生成默認(rèn)情況下編譯后生成的是hex文件,不過(guò)很輕松可以生成bin文件。介紹具體怎么生成bin文件,工具的話是使用fromelf.exe(目錄一般是在Keil安裝目錄里面,本人的fromelf.exe目錄是在C:\Keil\ARM\ARMCC\bin),我們是使用fromelf工具將axf文件轉(zhuǎn)換為bin文件。
熟悉命令行的同學(xué)可能會(huì)選擇直接敲命令,不過(guò)這里介紹使用RVMDK提供的用戶命令(編譯時(shí)可以自動(dòng)生成bin,省去每次生成bin文件都要敲命令的過(guò)程)。
打開TargetOption...,切換到User選項(xiàng)卡,如下
主要是在運(yùn)行用戶命令,Run#1
具體命令是(記得在Run#1前打勾,才會(huì)在編譯后執(zhí)行用戶命令生成bin文件):
C:\Keil\ARM\ARMCC\bin\fromelf.exe
--bin
-o
.\Output\MY_STM32.bin
.\Output\MY_STM32.axf
命令可以分為五部分,簡(jiǎn)化后是fromelf --bin  -o xxx.bin  xxx.axf,需要注意的是命令的五個(gè)部分之間要有空格。還需要說(shuō)明的是路徑問(wèn)題,這里的路徑都是相對(duì).uvproj文件的,下面是我的目錄(注意MY_STM32.uvproj文件和Output文件夾)。

我的bin文件和axf文件都在Output文件夾里面,并且路徑是相對(duì)MY_STM32.uvproj的,Output文件夾里的bin文件(MY_STM32.bin)相對(duì)于MY_STM32.uvproj應(yīng)該寫成“.\Output\MY_STM32.bin”。
l      第一部分
這部分是fromelf.exe文件的路徑,根據(jù)自己的安裝目錄而變。我這里因?yàn)?/font>Keil是安裝在C盤的,所以我的路徑如下所示。
參考命令:C:\Keil\ARM\ARMCC\bin\fromelf.exe
l      第二部分
這部分是固定的,--bin表示生成bin文件。
參考命令:--bin
l      第三部分
這部分也是固定的,-o表示輸出。
參考命令:-o
l      第四部分
這部分是生成文件的目錄和文件名,我是輸出在Output文件夾的,也就是bin文件在Output文件夾里面。
參考命令:.\Output\MY_STM32.bin
l      第五部分
這部分是axf文件的目錄和文件名,我們的bin文件是根據(jù)axf文件生成的,也就是說(shuō)axf文件相當(dāng)于輸入,bin文件相當(dāng)于輸出。我的axf文件也在Output文件夾的。
參考命令:.\Output\MY_STM32.axf
介紹了這些基本知識(shí)后,我們可以來(lái)實(shí)現(xiàn)BootLoader了。


4. 分幾步實(shí)現(xiàn)BootLoader有了前面的基礎(chǔ)知識(shí)后,應(yīng)該是比較容易理解BootLoader需要怎么實(shí)現(xiàn)了。這一章,我們分幾個(gè)步驟,一步一步實(shí)現(xiàn)BootLoader。
4.1       FAT文件系統(tǒng)我們的BootLoader是從SD卡更新程序的,把在電腦上編譯后的App程序,也就是bin文件,復(fù)制到SD卡中,然后讓單片機(jī)讀取相應(yīng)的bin文件,就可以實(shí)現(xiàn)程序的更新。需要注意的是,App程序需要修改ROM的起始地址,再編譯,并且要生成bin文件才支持正常下載。
我跑的文件系統(tǒng)是FATFS_R0.07c,很經(jīng)典的一個(gè)版本。如果大家對(duì)文件系統(tǒng)方面不了解的話,請(qǐng)自己網(wǎng)上查找教程,或者說(shuō)很多同學(xué)對(duì)這一步應(yīng)該已經(jīng)很熟悉啦。
只要單片機(jī)上實(shí)現(xiàn)讀取bin文件,結(jié)合Flash寫入程序,就可以實(shí)現(xiàn)程序更新。下面介紹讀寫Flash
4.2       讀寫Flash程序要實(shí)現(xiàn)BootLoader,還有一個(gè)前提是可以寫入Flash了。如果是STM32單片機(jī)的話是很容易實(shí)現(xiàn)的,因?yàn)槲覀冇泄俜綆?kù)。本人使用的是3.0.0版本,參考官方例程,很容易實(shí)現(xiàn)Flash的讀寫,這里同樣是為了實(shí)現(xiàn)BootLoader簡(jiǎn)單介紹一下。
4.2.1   Flash寫入步驟l      解鎖Flash
l      擦除Flash
l      寫入Flash
l      驗(yàn)證讀寫是否正確
4.2.2   讀寫Flash調(diào)用的庫(kù)函數(shù)l      voidFLASH_Unlock(void)                                     Flash解鎖
l      FLASH_Status FLASH_ErasePage(uint32_tPage_Address)           Flash擦除
l      FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_tData)  Flash寫入
4.2.3   實(shí)現(xiàn)Flash讀寫稍微封裝一下STM32的官方庫(kù)函數(shù),就能實(shí)現(xiàn)Flash的讀寫,并驗(yàn)證讀寫是否正確,具體我實(shí)現(xiàn)的接口函數(shù)為以下截圖,大家可以參考一下:
來(lái)到這里,我們可以實(shí)現(xiàn)在bin文件寫入Flash了,寫入完后,就要跳轉(zhuǎn)到App程序執(zhí)行了,接下來(lái)繼續(xù)介紹。
4.3       跳轉(zhuǎn)到新程序運(yùn)行
  這一節(jié)要結(jié)合上面提到過(guò)的,Cortex-M3啟動(dòng)做了什么事情,然后我們的BootLoader下載App程序后,App程序就需要做同樣的事情。主要有三個(gè)步驟,其中BootLoader程序需要做的是:
l      跳轉(zhuǎn)到復(fù)位向量
App需要做的是:
l      重定位中斷向量表
l      設(shè)置棧指針
4.3.1   跳轉(zhuǎn)到復(fù)位向量BootLoader程序需要做的是跳轉(zhuǎn)到復(fù)位向量,具體實(shí)現(xiàn)可以參考以下代碼。
( (void (*)()) (Reset))();   //跳轉(zhuǎn)到復(fù)位向量
注意( (void (*)()) (Reset) )();是一去就不返回的,執(zhí)行完這條語(yǔ)句,單片機(jī)就直接跳轉(zhuǎn)到App程序運(yùn)行的,所以BootLoader程序下載完App后,做一些簡(jiǎn)單的處理(根據(jù)自己的應(yīng)用,也可以不做任何處理),就用這條語(yǔ)句跳轉(zhuǎn)到App執(zhí)行。
4.3.2   App開始運(yùn)行BootLoader跳轉(zhuǎn)到App后,App需要做的是先設(shè)置棧指針,然后重定位中斷向量表地址,具體可以參考以下代碼。
__set_MSP( Msp);                 //設(shè)置棧指針
NVIC_SetVectorTable( base, offset);   //重定位中斷向量表
其中Msp是棧指針,也就是中斷向量表第一個(gè)字的內(nèi)容,我們這里的內(nèi)容是*((uint32_t)(0x08070000) )
base是中斷向量表的基地址,一般情況下就是ROM的起始地址,這里是0x08070000。
至此,BootLoader實(shí)現(xiàn)步驟完了,相信熟悉了這幾個(gè)步驟后,大家可以自己給自己的單片機(jī)寫個(gè)BootLoader。順便說(shuō)一下,Cortex-M4BootLoaderCortex-M3幾乎是一樣的。我在STM32上的實(shí)現(xiàn)完全是參考自己上次在飛思卡爾Cortex-M4上的實(shí)現(xiàn)。下面說(shuō)一下我的主函數(shù)吧,我們?cè)倏纯淳唧w的BootLoader流程,再熟悉一下BootLoader。


5.Bootloader具體流程
  先看看我的主函數(shù),再啰嗦一下具體流程,可能有的同學(xué)已經(jīng)有點(diǎn)厭煩啦,其實(shí)感覺有點(diǎn)多余。
5.1       主函數(shù)流程先看截圖。
主函數(shù)的流程如下所示:
l      時(shí)鐘初始化
l      LED初始化(無(wú)關(guān)緊要)
l      調(diào)試接口初始化(無(wú)關(guān)緊要)
l      Flash初始化(解鎖Flash
l      FAT初始化(掛載文件系統(tǒng))
l      我們的BootLoader(重點(diǎn),下面展開繼續(xù)介紹)
l      主循環(huán)(實(shí)際不會(huì)運(yùn)行到這里)
然后在具體講解BootLoader_FromSDCard函數(shù),這就是我們的重點(diǎn),傳說(shuō)中STM32BootLoaderSD卡更新固件。
5.2       BootLoader流程
老樣子,先上截圖:
具體流程如下所示:
l      打開bin文件,檢查文件打開是否正確
l      設(shè)置Flash下載起始地址(App程序起始地址)
l      讀取bin文件,檢查讀取是否正確
l      獲取棧指針SP和復(fù)位向量PC
l      進(jìn)入循環(huán)(這里是第5步),條件為如果讀取bin文件字節(jié)數(shù)不為零
l      將讀取到的bin寫入Flash,并判寫入狀態(tài)
l      調(diào)整Flash地址,根據(jù)寫入字節(jié)調(diào)整
l      繼續(xù)讀取bin文件,檢查讀取是否正確,回到5繼續(xù)循環(huán)
來(lái)到這里已經(jīng)是退出循環(huán)了,也就是說(shuō)我們已經(jīng)將bin寫入Flash完成了,準(zhǔn)備跳轉(zhuǎn)到新程序運(yùn)行
5.3       跳轉(zhuǎn)到新程序流程其實(shí)上面已經(jīng)講過(guò)了,這里繼續(xù)啰嗦,截圖:
l      重定位中斷向量
l      設(shè)置棧指針
l      跳轉(zhuǎn)到復(fù)位向量(開始運(yùn)行App程序)
說(shuō)明一下,在這里重定位中斷向量其實(shí)是多余的,App程序執(zhí)行初始化后,又回到STM32初始狀態(tài),所以在App程序中需要執(zhí)行重定位中斷向量表操作,具體同以上操作相同。
啰嗦了又一遍,BootLoader完全結(jié)束,感謝大家都支持啦~
附錄A 主函數(shù)


#include "main.h"
int main(void)
{
        SystemInit();                                               //配置系統(tǒng)時(shí)鐘為72M
   
   LED_GPIO_Config();                            //初始化LED端口
   Debug_TraceIOEnable();                          //使能調(diào)試printfIO
   
   Flash_Init();                                     //初始化Flash
   FAT_Init();                                      //初始化文件系統(tǒng)
   
   BootLoader_FromSDCard();                        //BootloaderSD卡更新固件

   while(1)
        {
       LED_StatShow( FuncErr);                     //LED顯示Bootloader狀態(tài)
        }      
}



   

附錄B 更新說(shuō)明
l      版本:V1.01
l      時(shí)間:2014-4-8
l      作者:coolweedman
l      更新:說(shuō)明Bootloader程序和App程序需要配合才能實(shí)現(xiàn)BootLoader,App程序需要重定位中斷向量表
l      特別感謝:網(wǎng)友cary_yingj的研究和分享


參考文獻(xiàn)
[1]     CM3權(quán)威指南CnR2Joseph Yiu   宋巖
[2]     ST官方庫(kù)3.0.0
[3]     C和指針》KennethA. Reek  徐波
[4]     FATFS文件系統(tǒng)
[5]     其他互聯(lián)網(wǎng)資料

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
spdian131 + 5 贊一個(gè)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏11 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:135365 發(fā)表于 2016-7-28 16:39 | 只看該作者
不錯(cuò)的
回復(fù)

使用道具 舉報(bào)

板凳
ID:137617 發(fā)表于 2016-8-25 21:57 | 只看該作者
贊一個(gè)!
回復(fù)

使用道具 舉報(bào)

地板
ID:143134 發(fā)表于 2016-10-17 22:06 | 只看該作者
感謝樓主分享的文章,專門注冊(cè)個(gè)號(hào),頂貼!
回復(fù)

使用道具 舉報(bào)

5#
ID:142965 發(fā)表于 2016-10-17 22:50 | 只看該作者

 謝謝分享了
回復(fù)

使用道具 舉報(bào)

6#
ID:143542 發(fā)表于 2016-10-20 09:52 | 只看該作者
21icbbs 上有這些資料
回復(fù)

使用道具 舉報(bào)

7#
ID:154038 發(fā)表于 2016-12-12 08:56 | 只看該作者
不錯(cuò),紫薯,補(bǔ)丁
回復(fù)

使用道具 舉報(bào)

8#
ID:93036 發(fā)表于 2016-12-20 18:13 | 只看該作者
寫的不錯(cuò)!多謝樓主!
回復(fù)

使用道具 舉報(bào)

9#
ID:156880 發(fā)表于 2016-12-22 17:26 | 只看該作者
很好學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

10#
ID:153777 發(fā)表于 2017-1-7 15:06 | 只看該作者
感謝樓主分享的文章,專門注冊(cè)個(gè)號(hào),頂貼!
回復(fù)

使用道具 舉報(bào)

11#
ID:43813 發(fā)表于 2017-10-10 19:29 | 只看該作者
看完樓主的帖子,思路非常清晰,受益匪淺
回復(fù)

使用道具 舉報(bào)

12#
ID:287050 發(fā)表于 2018-3-2 21:06 | 只看該作者
感謝分享,,,,
回復(fù)

使用道具 舉報(bào)

13#
ID:298277 發(fā)表于 2018-3-28 13:56 | 只看該作者
贊一個(gè)!
回復(fù)

使用道具 舉報(bào)

14#
ID:108573 發(fā)表于 2020-7-4 09:50 | 只看該作者
寫的不錯(cuò),不過(guò)想請(qǐng)教個(gè)問(wèn)題。有些程序是在APP中有一個(gè)系統(tǒng)升級(jí)的選項(xiàng),點(diǎn)進(jìn)去,找到SD卡的固件進(jìn)行升級(jí)。這樣是不是bootloader和APP是二合一的,flash空間夠用嗎,這種是怎么實(shí)現(xiàn)的?有人這樣做嗎,求教
回復(fù)

使用道具 舉報(bào)

15#
ID:764088 發(fā)表于 2020-7-6 15:01 | 只看該作者
感恩樓主分享,學(xué)習(xí)收藏
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表