久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    STM32的BootLoader 從SD卡更新固件

     ada_lib 2015-01-27

    STM32BootLoader SD卡更新固件


    by  coolweedman

    2013-11-13 23:07:26



     

    1. 前言

    2. 初識BootLoader

    2.1      百度百科的BootLoader

    2.2      BootLoader的簡單理解

    2.3      BootLoader的作用

    3. BootLoader預(yù)備知識

    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語言的函數(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. 分幾步實現(xiàn)BootLoader

    4.1      FAT文件系統(tǒng)

    4.2      讀寫Flash程序

    4.2.1       Flash寫入步驟

    4.2.2       讀寫Flash調(diào)用的庫函數(shù)

    4.2.3       實現(xiàn)Flash讀寫

    4.3      跳轉(zhuǎn)到新程序運行

    4.3.1       跳轉(zhuǎn)到復(fù)位向量

    4.3.2       App開始運行

    5. Bootloader具體流程

    5.1      主函數(shù)流程

    5.2      BootLoader流程

    5.3      跳轉(zhuǎn)到新程序流程

    附錄A 主函數(shù)

    附錄B 更新說明

    參考文獻



    1. 前言

    自從幾個月前接觸到有Bootloader這回事,就有一種強烈的沖動,想寫一個BootLoader出來。很快在飛思卡爾的Cortex-M4單片機上實現(xiàn),已經(jīng)是好幾個月前的事情了。然后關(guān)于BootLoader的事擱在一邊好久了,這次弄個STM32BootLoader出來,Cortex-M3的,順便發(fā)表下博客,跟大家分享一下。

    。。。

    又過了大半年了吧,慢慢對BootLoader的認識也有點長進啦。特別是跟網(wǎng)友討論后發(fā)現(xiàn)BootLoader的實現(xiàn)還是需要靠BootLoader程序和App程序的配合才能正常使用。在這里特別感謝網(wǎng)友cary_yingj ,對本BootLoader的研究后發(fā)現(xiàn)App程序需要重定位中斷向量表,才能正常工作。

    在其他網(wǎng)友的反饋下,本人準(zhǔn)備再將次文檔完善,把不夠詳細的地方寫得再詳細,并且力求通俗易懂一點。希望對學(xué)習(xí)BootLoader的同學(xué)們有所幫助。



    2. 初識BootLoader

    可能有的同學(xué)聽說過BootLoader,有的同學(xué)沒有聽說過,這個都很正常。關(guān)于BootLoader的概念大家可以上網(wǎng)查一下,有比較詳細的說明,我在這里說說我自己比較片面的理解,并且是針對Cortex M3說明的,實現(xiàn)平臺為STM32F103VET6

    2.1        百度百科的BootLoader

    這里借用一下百度百科對BootLoader的解釋。在嵌入式操作系統(tǒng)中,BootLoader是在操作系統(tǒng)內(nèi)核運行之前運行。可以初始化硬件設(shè)備、建立內(nèi)存空間映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。在嵌入式系統(tǒng)中,通常并沒有像BIOS那樣的固件程序(注,有的嵌入式CPU也會內(nèi)嵌一段短小的啟動程序),因此整個系統(tǒng)的加載啟動任務(wù)就完全由BootLoader來完成。在一個基于ARM7TDMI core的嵌入式系統(tǒng)中,系統(tǒng)在上電或復(fù)位時通常都從地址0x00000000處開始執(zhí)行,而在這個地址處安排的通常就是系統(tǒng)的BootLoader程序。

    2.2        BootLoader的簡單理解

    BootLoader就是單片機啟動時候運行的一段小程序,這段程序負責(zé)單片機固件更新,也就是單片機選擇性的自己給自己下程序。可以更新也可以不更新,更新的話,BootLoader更新完程序后,跳轉(zhuǎn)到新程序運行;不更新的話,BootLoader直接跳轉(zhuǎn)到原來的程序去運行。

      需要注意的是:BootLoader下載新程序后并不擦除自己(BootLoader程序還在),下次啟動依然先運行BootLoader程序,又可以選擇性的更新或者不更新程序,所以BootLoader就是用來管理單片機程序的更新。

      這是本人的大概理解,大家有不明白請網(wǎng)上搜索一下更詳細介紹吧。

    2.3        BootLoader的作用

    BootLoader使單片機能自己給自己下載程序,所以在程序升級方面非常有作用。比如我們的BootLoader是通過GSM更新程序的,我們在升級單片機程序的時候,只要把新程序通過GSM發(fā)送給單片機,單片機自己實現(xiàn)程序更新,然后跳轉(zhuǎn)到新程序執(zhí)行,這樣就省去我們很多升級的功夫啦。

    可以想象一下如果把單片機安裝在非常高的地方,或者危險的工業(yè)現(xiàn)場,或者封裝得很難拆下來,我們很難直接給單片機下載程序,那么BootLoader的作用就體現(xiàn)出來了。簡單的說,有了BootLoader,我們更新程序的話是省心又省力。

    想想是不是很高級,還帶點小興奮哈哈。不用急,下面我們會繼續(xù)介紹,讓大家都能自己實現(xiàn)BootLoader。至于是通過什么方式升級,這個大家自由發(fā)揮,相信會設(shè)計出豐富多彩的BootLoader升級方式呢。


    3. BootLoader預(yù)備知識

    我們這里是為ARMCortex-M3單片機寫的BootLoader,需要了解一下M3內(nèi)核的架構(gòu),并且要了解M3單片機是怎么啟動的等等。這個方面的知識,可以參考《Cortex-M3權(quán)威指南》,這里的話我只是為了實現(xiàn)BootLoader簡單介紹一下,大家有什么不清楚的請參考權(quán)威指南。并且這里是以STM32為例說明問題的,使用的開發(fā)環(huán)境是RVMDKKeil)。

    3.1        復(fù)位序列

    這里參考的是《Cortex-M3權(quán)威指南》的3.8節(jié),復(fù)位序列。

    M3單片機復(fù)位后,從0x00000000取棧指針(SP), 0x00000004取復(fù)位向量(PC),有了棧指針和復(fù)位向量后,單片機就按照正常流程運行了,在BootLoader里面,我們更新完程序后需要做的步驟之一就是設(shè)置棧指針,跳轉(zhuǎn)到復(fù)位向量。

    3.1.1    棧指針

    棧是一種數(shù)據(jù)結(jié)構(gòu),后進先出LIFO。借用百度百科的解釋:棧由編譯器自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。它使用的是一級緩存,他們通常都是被調(diào)用時處于存儲空間中,調(diào)用完畢立即釋放。

    3.1.2    復(fù)位向量

    復(fù)位向量是一個函數(shù)地址,在Cortex M3單片機里是復(fù)位函數(shù)的地址。也就是單片機啟動后第一個執(zhí)行的函數(shù)。

    3.2        重定位中斷向量表

    這里參考《Cortex-M3權(quán)威指南》的7.3節(jié),向量表。

    BootLoader是一個完整的程序,下載的新程序(以下稱為App)也是一個完整的程序。都包含中斷向量表,所以的話,我們是有兩個中斷向量表,相信因為有兩個向量表,大家都知道我們應(yīng)該需要對這兩個向量表做點什么吧。

    3.2.1    STM32的中斷向量表

    我們只看前16個向量,因為其余的向量屬于外設(shè)使用,與Cortex M3內(nèi)核無關(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                            ; Reserved

                    DCD                            ; Reserved

                    DCD                            ; Reserved

                    DCD                            ; Reserved

                    DCD     SVC_Handler               ; SVCall Handler

                    DCD     DebugMon_Handler          ; Debug Monitor Handler

                    DCD                            ; Reserved

                    DCD     PendSV_Handler            ; PendSV Handler

                    DCD     SysTick_Handler           ; SysTick Handler

    __initial_spTop就是棧指針Reset_Handler是復(fù)位向量。這里只顯示了16個向量,CortexM3單片機的話總共有256個向量,也就是從棧指針的地址開始有1KB的區(qū)域?qū)儆谥袛嘞蛄勘怼?/span>

    單片機啟動默認先運行BootLoader,所以默認的中斷向量表位置是BootLoader的中斷向量表。為了App可以正常運行,下載完App后,我們還需要把中斷向量表重新定位到App程序那里。根據(jù)《Cortex M3權(quán)威指南》,介紹一下怎樣重定位中斷向量表。

    3.2.2    設(shè)置中斷向量表偏移

    Cortex-M3單片機有一個管理中斷向量表的寄存器叫做向量表偏移量寄存器(VTOR)地址0xE000_ED08。具體可以看看截圖:

    STM32的BootLoader <wbr>從SD卡更新固件

    STM332程序的起始地址一般在0x08000000。所以BootLoader程序是在0x08000000,不是在0x00000000是因為STM32的重映射技術(shù)(不符合Cortex-M3的設(shè)計,有點搞另類的感覺)。所以BootLoader的中斷向量表在0x08000000那里。如果我們的App程序起始地址在0x08070000,并且App的中斷向量表在起始地址,那么BootLoader程序下載App后,為了App程序能正確運行,開始App程序的運行后第一步,就要把中斷向量表重定位到0x08070000那里。

    具體實現(xiàn)下面會再介紹,接下來介紹分散加載文件相關(guān)內(nèi)容。

    3.3        分散加載文件相關(guān)

    這一節(jié)涉及的內(nèi)容主要屬于分散加載文件,大家具體上網(wǎng)了解,這里只是介紹了能夠?qū)崿F(xiàn)BootLoader的一小部分。

    3.3.1    C語言的函數(shù)地址

    我們知道C語言的函數(shù)名就是函數(shù)的地址,并且STM32單片機ROM的起始地址是在0x08000000,那么使用編譯器編譯程序的話(這里使用的是RVMDK),函數(shù)的地址默認都在以0x08000000為首的一段ROM里面了。比如我們一個函數(shù)Delay(),它的地址可以是0x08000167Cortex M3中函數(shù)的地址0bit位一般是1),也就是Delay函數(shù)的代碼在0x08000167C語言函數(shù)調(diào)用Delay時,就是執(zhí)行0x08000167的代碼。

    3.3.2    BootLoader占用的ROM

    我們需要注意的問題是,如果不修改程序默認的起始地址的話,那么BootLoader和新App程序的起始地址都是0x08000000,也就是他們重疊了(代碼重疊),這樣的話肯定相互之間有影響,程序是不能正常工作的。

    這里的解決方法是,BootLoader程序依然占用0x08000000為首的那段ROM,因為STM32的默認就是從0x08000000運行程序的。保持BootLoader程序先能正確運行。然后App使用除BootLoader占用ROM以外的空間。這里需要知道BootLoader到底占用了多少ROM,很簡單,查看MAP文件就行了。這里以我的BootLoaderMAP文件為例說明一下,看截圖:

    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這句話說明了我的BootLoader程序是從0x08000000開始,占用了0x00006DA4大小。只要我們的App不要和BootLoader程序占用的空間沖突就可以了。我的App程序的起始地址選擇為0x08070000,不與BootLoader程序沖突。具體怎么修改ROM起始地址,下面介紹。

    3.3.3    修改ROM起始地址

    編譯新程序的時候,我們要修改程序的起始地址,我的修改方法如下(開發(fā)環(huán)境是RVMDK):打開Target Option...,切換到Target選項卡,如下

    STM32的BootLoader <wbr>從SD卡更新固件

    修改IROM1的起始地址和長度:

    比如,為了不產(chǎn)生地址沖突,我將起始地址0x08000000修改成0x0807000,將ROM長度0x80000修改成0x10000。如下圖所示(左圖為修改前、右圖為修改后):

    STM32的BootLoader <wbr>從SD卡更新固件  STM32的BootLoader <wbr>從SD卡更新固件

    注意:BootLoader程序是不需要修改的,只是App需要修改(App就是使用BootLoader下載的程序)。

    3.4        hex文件和bin文件

    3.4.1    hex文件

    平時我們用j-Link或者串口下載程序的話,都是打開hex文件下載的,因為hex文件包含地址信息,下載程序的時候知道程序下載到ROM的哪個區(qū)域。從另一個角度上說,也就是hex文件是不能直接寫進ROM的,一邊寫需要一邊轉(zhuǎn)換(解碼出地址信息,將對應(yīng)內(nèi)容寫入ROM)。

    3.4.2    bin文件

    bin文件的話,很好理解,是直接的可執(zhí)行代碼。也就是bin文件的內(nèi)容跟下載ROM里面的內(nèi)容是一樣的。bin文件是沒有包含地址信息的,所以在下載之前要知道bin文件是要下載到ROM的那個區(qū)域。

    我們的BootLoader下載的是bin文件,直接寫進STM32Flash里面,地址信息的話就是上一節(jié)的IROM0x08070000,從0x08070000開始連續(xù)寫入,中間不間斷。

    3.5        Bin文件生成

    默認情況下編譯后生成的是hex文件,不過很輕松可以生成bin文件。介紹具體怎么生成bin文件,工具的話是使用fromelf.exe(目錄一般是在Keil安裝目錄里面,本人的fromelf.exe目錄是在C:\Keil\ARM\ARMCC\bin),我們是使用fromelf工具將axf文件轉(zhuǎn)換為bin文件。

    熟悉命令行的同學(xué)可能會選擇直接敲命令,不過這里介紹使用RVMDK提供的用戶命令(編譯時可以自動生成bin,省去每次生成bin文件都要敲命令的過程)。

    打開Target Option...,切換到User選項卡,如下

    STM32的BootLoader <wbr>從SD卡更新固件

    主要是在運行用戶命令,Run #1

    STM32的BootLoader <wbr>從SD卡更新固件

    具體命令是(記得在Run #1前打勾,才會在編譯后執(zhí)行用戶命令生成bin文件):

    C:\Keil\ARM\ARMCC\bin\fromelf.exe

    --bin

    -o

    .\Output\MY_STM32.bin

    .\Output\MY_STM32.axf

    命令可以分為五部分,簡化后是fromelf  --bin  -o  xxx.bin  xxx.axf,需要注意的是命令的五個部分之間要有空格。還需要說明的是路徑問題,這里的路徑都是相對.uvproj文件的,下面是我的目錄(注意MY_STM32.uvproj文件和Output文件夾)。

    STM32的BootLoader <wbr>從SD卡更新固件

    我的bin文件和axf文件都在Output文件夾里面,并且路徑是相對MY_STM32.uvproj的,Output文件夾里的bin文件(MY_STM32.bin)相對于MY_STM32.uvproj應(yīng)該寫成“.\Output\MY_STM32.bin”

    l       第一部分

    這部分是fromelf.exe文件的路徑,根據(jù)自己的安裝目錄而變。我這里因為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文件生成的,也就是說axf文件相當(dāng)于輸入,bin文件相當(dāng)于輸出。我的axf文件也在Output文件夾的。

    參考命令:.\Output\MY_STM32.axf

    介紹了這些基本知識后,我們可以來實現(xiàn)BootLoader了。


    4. 分幾步實現(xiàn)BootLoader

    有了前面的基礎(chǔ)知識后,應(yīng)該是比較容易理解BootLoader需要怎么實現(xiàn)了。這一章,我們分幾個步驟,一步一步實現(xiàn)BootLoader

    4.1        FAT文件系統(tǒng)

    我們的BootLoader是從SD卡更新程序的,把在電腦上編譯后的App程序,也就是bin文件,復(fù)制到SD卡中,然后讓單片機讀取相應(yīng)的bin文件,就可以實現(xiàn)程序的更新。需要注意的是,App程序需要修改ROM的起始地址,再編譯,并且要生成bin文件才支持正常下載。

    我跑的文件系統(tǒng)是FATFS_R0.07c,很經(jīng)典的一個版本。如果大家對文件系統(tǒng)方面不了解的話,請自己網(wǎng)上查找教程,或者說很多同學(xué)對這一步應(yīng)該已經(jīng)很熟悉啦。

    只要單片機上實現(xiàn)讀取bin文件,結(jié)合Flash寫入程序,就可以實現(xiàn)程序更新。下面介紹讀寫Flash

    4.2        讀寫Flash程序

    要實現(xiàn)BootLoader,還有一個前提是可以寫入Flash了。如果是STM32單片機的話是很容易實現(xiàn)的,因為我們有官方庫。本人使用的是3.0.0版本,參考官方例程,很容易實現(xiàn)Flash的讀寫,這里同樣是為了實現(xiàn)BootLoader簡單介紹一下。

    4.2.1    Flash寫入步驟

    l       解鎖Flash

    l       擦除Flash

    l       寫入Flash

    l       驗證讀寫是否正確

    4.2.2    讀寫Flash調(diào)用的庫函數(shù)

    l       void FLASH_Unlock(void)                                      Flash解鎖

    l       FLASH_Status FLASH_ErasePage(uint32_t Page_Address)            Flash擦除

    l       FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)  Flash寫入

    4.2.3    實現(xiàn)Flash讀寫

    稍微封裝一下STM32的官方庫函數(shù),就能實現(xiàn)Flash的讀寫,并驗證讀寫是否正確,具體我實現(xiàn)的接口函數(shù)為以下截圖,大家可以參考一下:

    STM32的BootLoader <wbr>從SD卡更新固件

    來到這里,我們可以實現(xiàn)在bin文件寫入Flash了,寫入完后,就要跳轉(zhuǎn)到App程序執(zhí)行了,接下來繼續(xù)介紹。

    4.3        跳轉(zhuǎn)到新程序運行

      這一節(jié)要結(jié)合上面提到過的,Cortex-M3啟動做了什么事情,然后我們的BootLoader下載App程序后,App程序就需要做同樣的事情。主要有三個步驟,其中BootLoader程序需要做的是:

    l       跳轉(zhuǎn)到復(fù)位向量

    App需要做的是:

    l       重定位中斷向量表

    l       設(shè)置棧指針

    4.3.1    跳轉(zhuǎn)到復(fù)位向量

    BootLoader程序需要做的是跳轉(zhuǎn)到復(fù)位向量,具體實現(xiàn)可以參考以下代碼。

     ( (void (*)()) (Reset) )();    //跳轉(zhuǎn)到復(fù)位向量

    注意 ( (void (*)()) (Reset) )();是一去就不返回的,執(zhí)行完這條語句,單片機就直接跳轉(zhuǎn)到App程序運行的,所以BootLoader程序下載完App后,做一些簡單的處理(根據(jù)自己的應(yīng)用,也可以不做任何處理),就用這條語句跳轉(zhuǎn)到App執(zhí)行。

    4.3.2    App開始運行

    BootLoader跳轉(zhuǎn)到App后,App需要做的是先設(shè)置棧指針,然后重定位中斷向量表地址,具體可以參考以下代碼。

    __set_MSP( Msp );                  //設(shè)置棧指針

    NVIC_SetVectorTable( base, offset );    //重定位中斷向量表

    其中Msp是棧指針,也就是中斷向量表第一個字的內(nèi)容,我們這里的內(nèi)容是*( (uint32_t)(0x08070000) )

    base是中斷向量表的基地址,一般情況下就是ROM的起始地址,這里是0x08070000

    至此,BootLoader實現(xiàn)步驟完了,相信熟悉了這幾個步驟后,大家可以自己給自己的單片機寫個BootLoader。順便說一下,Cortex-M4BootLoaderCortex-M3幾乎是一樣的。我在STM32上的實現(xiàn)完全是參考自己上次在飛思卡爾Cortex-M4上的實現(xiàn)。下面說一下我的主函數(shù)吧,我們再看看具體的BootLoader流程,再熟悉一下BootLoader


    5. Bootloader具體流程

      先看看我的主函數(shù),再啰嗦一下具體流程,可能有的同學(xué)已經(jīng)有點厭煩啦,其實感覺有點多余。

    5.1        主函數(shù)流程

    先看截圖。

    STM32的BootLoader <wbr>從SD卡更新固件

    主函數(shù)的流程如下所示:

    l       時鐘初始化

    l       LED初始化(無關(guān)緊要)

    l       調(diào)試接口初始化(無關(guān)緊要)

    l       Flash初始化(解鎖Flash

    l       FAT初始化(掛載文件系統(tǒng))

    l       我們的BootLoader(重點,下面展開繼續(xù)介紹)

    l       主循環(huán)(實際不會運行到這里)

    然后在具體講解BootLoader_FromSDCard函數(shù),這就是我們的重點,傳說中STM32BootLoaderSD卡更新固件。

    5.2        BootLoader流程

    老樣子,先上截圖:

    STM32的BootLoader <wbr>從SD卡更新固件

    具體流程如下所示:

    l       打開bin文件,檢查文件打開是否正確

    l       設(shè)置Flash下載起始地址(App程序起始地址)

    l       讀取bin文件,檢查讀取是否正確

    l       獲取棧指針SP和復(fù)位向量PC

    l       進入循環(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)

    來到這里已經(jīng)是退出循環(huán)了,也就是說我們已經(jīng)將bin寫入Flash完成了,準(zhǔn)備跳轉(zhuǎn)到新程序運行

    5.3        跳轉(zhuǎn)到新程序流程

    其實上面已經(jīng)講過了,這里繼續(xù)啰嗦,截圖:

    STM32的BootLoader <wbr>從SD卡更新固件

    l       重定位中斷向量

    l       設(shè)置棧指針

    l       跳轉(zhuǎn)到復(fù)位向量(開始運行App程序)

    說明一下,在這里重定位中斷向量其實是多余的,App程序執(zhí)行初始化后,又回到STM32初始狀態(tài),所以在App程序中需要執(zhí)行重定位中斷向量表操作,具體同以上操作相同。

    啰嗦了又一遍,BootLoader完全結(jié)束,感謝大家都支持啦~

    附錄A 主函數(shù)

     

     

    #include "main.h"

    int main(void)

    {

             SystemInit();                                                 //配置系統(tǒng)時鐘為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 更新說明

    l       版本:V1.01

    l       時間:2014-4-8

    l       作者:coolweedman

    l       更新:說明Bootloader程序和App程序需要配合才能實現(xiàn)BootLoaderApp程序需要重定位中斷向量表

    l       特別感謝:網(wǎng)友cary_yingj的研究和分享


    參考文獻

    [1]      CM3權(quán)威指南CnR2Joseph Yiu    宋巖

    [2]      ST官方庫3.0.0

    [3]      C和指針》Kenneth A. Reek   徐波

    [4]      FATFS文件系統(tǒng)

    [5]      其他互聯(lián)網(wǎng)資料

     

    最后來一個廣告,本工程源代碼等資料,歡迎索取:

     

      本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
      轉(zhuǎn)藏 分享 獻花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 日韩有码中文字幕国产| 96在线看片免费视频国产| 国产精品亚洲LV粉色| 国产精品大片中文字幕| 国产精品专区第1页| 波多野结衣AV一区二区全免费观看 | 国产精品午夜福利91| 精品剧情V国产在线观看| 99久久99久久加热有精品| 人妻系列无码专区免费| 强奷乱码中文字幕熟女导航 | 日本欧美一区二区三区在线播放| 欧美成本人视频免费播放| 亚洲 欧美 国产 制服 动漫| 天堂V亚洲国产V第一次| AAA级久久久精品无码片| A毛片终身免费观看网站| 亚洲欧美日韩中文字幕一区二区三区| 国产第一页浮力影院入口| A级日本乱理伦片免费入口| 国产一区二区三区在线观看免费| 做暖暖视频在线看片免费| 麻豆国产va免费精品高清在线| 337P日本欧洲亚洲大胆精品555588| 亚洲精品动漫免费二区| 久久99精品久久久久久齐齐| 精品国产高清中文字幕| 宅男666在线永久免费观看| 2019久久久高清日本道| 中文 在线 日韩 亚洲 欧美| 久久97人人超人人超碰超国产| 26uuu另类亚洲欧美日本| 丰满少妇人妻HD高清大乳在线| 美乳丰满人妻无码视频| 国产99视频精品免费专区| 在线天堂中文官网| 无码成人午夜在线观看 | 国产午夜A理论毛片| 人妻中文无码久热丝袜| 亚洲电影天堂在线国语对白| 在线 | 18精品免费1区2|