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向量表偏移设置STM32 + Bootloader +射频\串口远程升级_第1张图片

图:iar调试烧写设置

STM32 + Bootloader +射频\串口远程升级_第2张图片

程序复位时,运行地址-->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、跳转之前,在没有先关闭时钟的情况下,关闭了外部高速晶振,导致异常死机

 

你可能感兴趣的:(STM32 + Bootloader +射频\串口远程升级)