STM32 + Bootloader +射頻\串口遠程升級

STM32+Bootloader 通過射頻\串口進行程序的遠程升級 in-application programming (IAP)

程序可通過外部boot0,boot1引腳指定運行起始地址是sram或flash,以下爲通用的flash起始運行( Vector Table Relocation in Internal FLASH)

設計:1、程序復位後從app開始運行;2、接收並存儲升級文件;3、跳轉至bootloader運行,處理升級文件;4、軟件或硬件復位

設計也可將bootloader放在app前,每次重啓後先運行bootloader去檢測是否有升級文件,若有則升級,若沒有則跳轉到app區域運行。在app若收到升級文件,完成存儲校驗後重啓設備即可到bootloader進行升級。

1、內部flash區域規劃

/* (0x800 0000 ~ 0x800 efff) 60k */
#define AppAddress                            (FLASH_BASE)                            /* 0x8000000 */
#define AppCodePageSize                 (0x1e)                                            /* 用戶代碼APP區域  */
#define AppCodeSize                          (AppCodePageSize * FLASH_PAGE_SIZE)

/* (0x800 f000 ~ 0x801 2fff) 16k */
#define BootAddress                           (AppAddress + AppCodeSize)                           
#define BootPageSize                         (0x08)                                            /* 8頁的空間來存放Boot (16k) */
#define BootSize                                 (BootPageSize * FLASH_PAGE_SIZE)  
/* (0x801 3000 ~ 0x802 23ff) 62k */
#define AppImageAddress                  (BootAddress + BootSize)
#define AppImagePageSize                (0x1f)                                             /* 鏡像區 存放遠程升級文件 */
#define AppImageSize                        (AppImagePageSize * FLASH_PAGE_SIZE)
#define AppImageStartAddress           (AppImageAddress + FLASH_PAGE_SIZE)       /* 升級文件除去標誌後存放的具體位置 */ 

程序需在指定的flash地址運行,stm32起始地址0x08000000+VECT_TAB_OFFSET(SCB->VTOR),這就需考慮flash的規劃問題,簡單地說,就是把片內flash進行分區域,每個區域規劃存儲什麼數據的過程。以上app的SCB->VTOR = 0;bootloader的SCB->VTOR = 0xF000(0x1e * 2k = 60k);即app程序最大設計爲60k,bootloader最大設計爲16k,接收的升級文件最大也爲60k。

圖:bootloader向量表偏移設置

圖:iar調試燒寫設置

程序復位時,運行地址-->0x08000000

2、通過射頻或串口接收升級文件保存至flash規劃的AppImageAddress地址下。

3、接收完成後條用跳轉至bootloader。

void System_JumpToBootLoader(void)
{
     Bsp_DeInit();

    uint32_t JumpAddress = 0;
    pFunction Jump_To_BootLoader;

    /* Test if user code is programmed starting from address "BOOTLOADER_ADDRESS" */
    if(((*(__IO uint32_t*)BootAddress) & 0x2FFE0000) == 0x20000000) // DCD sfe(CSTACK) ; AppAddress
    {
        /* Jump to user application */
        JumpAddress = *(__IO uint32_t*) (BootAddress + 4);

        Jump_To_BootLoader = (pFunction) JumpAddress; // DCD Reset_Handler ;  AppAddress + 4

        /* Initialize user application's Stack Pointer */
        __set_MSP(*(__IO uint32_t*) BootAddress);

        Jump_To_BootLoader();
    }

}
在bootloader中處理校驗

void UD_CheckAndUpdata(void)

{
    if(!UD_CheckHead()) // 檢測flash內是否有升級文件,一些標誌,文件大小驗證
    {
        return;
    }

    UD_EraseUserApp(); // 以上驗證通過,開始擦除app應用數據,擦除AppAddress共60k 

    UD_UpDataUserApp();// 將升級文件寫入至app地址,從AppImageStartAddress開始搬移數據至AppAddress

    UD_EraseImageApp(); // 擦除升級文件AppImageAddress
}

4、重啓設備,程序再次運行-->0x08000000,即運行升級後的程序。

升級過程遇到的問題:

1、bootloader沒有進行餵狗,導致操作flash過程中出現異常死機

2、跳轉bootloader之前,內部時鐘,中斷標誌等沒有清除,跳轉到bootloader後,跳到了中斷中,導致程序死機。

3、跳轉之前,在沒有先關閉時鐘的情況下,關閉了外部高速晶振,導致異常死機

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章