关于bootloader升级跳转到APP

本文章是自己学习和编写代码过程中的学习总结,目的是写下笔记供以后自己查看,学习不算深入,并不是说指导别人怎么做,但是如果大家发现有什么问题欢迎指出。以下是在HC32F460PETB芯片上进行,可能与ST或者其他的芯片有一定的区别。

bootloader跳转APP

一般情况下,不带bootloader的话中断向量表的地址是从0x00000000开始,代码地址从0x00000004开始,如下图:
不带bootloader中断向量表地址

这种情况代码不支持升级,只能通过烧录器进行烧录擦写,无法后续通过上位机进行代码升级。此时则需要引入bootloader和APP(Application)的概念,代码正常运行以及所有的应用层逻辑都是在APP中,APP接收到升级指令并且握手成功之后则进行复位,进入bootloader中。bootloader中接收升级包的指令,并且将接收到的数据进行校验和保存到APP地址或者备份APP地址中,整包数据接收完之后在跳转回到APP中,此过程便完成代码升级。

分配空间大小及配置起始地址

在建立Bootloader和APP工程的时候我们需要提前想好bootloader和app各自需要多大的空间,以及起始地址是多少。
一般来说,bootloader的起始地址就是0x00000000,大小一般给到0x10000就已经足够了。APP地起始地址可以自己确认,APP的地址选择一下规则:
1、必须要大于bootloader的最大地址,也就是说bootloader的地址和APP的地址不允许有重叠。
2、APP的地址不一定需要和bootloader的地址连续,中间可以划分部分空间出来进行参数或者标志位的存储
3、bootloader里面的配置的APP跳转地址需要和工程上keil配置的ROM地址对应

下图为我的空间地址分配,其中bootloader的起始地址为0x000000,大小为0x00005FFF;APP起始地址为0x00010000,大小为0x0006FF00。中间分配了部分空间存储参数和标志位:
在这里插入图片描述
bootloader地址设置:
bootloader地址设置

APP地址设置:
APP地址设置

bootloader地址跳转

bootloader地址跳转有几个步骤:
1、判断跳转的栈地址是否合法
2、获取程序的起始地址
3、初始化堆栈地址
4、跳转到APP
以上步骤都是直接调用ARM内核的函数即可,基本都是通用

#define BOOTLOADER_STARTADDR       0x00000000
#define BOOTLOADER_ENDADDR         0x00005FFF
#define APP_STARTADDR              0x00010000
#define APP_ENDADDR                0x0007FF00

static uint32_t JumpAddr;
static func_ptr_t JumpToAppFunc;

void JumpToApp(void)
{
	/*获取栈顶地址*/
    uint32_t AppAddr = *((__IO uint32_t *)APP_STARTADDR);

    /* 检查栈顶地址是否合法 */
    if ((AppAddr > SRAM_BASE) && (AppAddr <= (SRAM_BASE + SRAM_SIZE)))
    {
        /* 获取程序起始地址 */
        JumpAddr = *(__IO uint32_t *)(APP_STARTADDR + 4U);
        JumpToAppFunc = (func_ptr_t)JumpAddr;
        /* 初始化APP堆栈指针 */
        __set_MSP(*(__IO uint32_t *)APP_STARTADDR);
        /*跳转到APP*/
        JumpToAppFunc();
    }
}

int main(void)
{
    __disable_irq();  // 关闭总中断,防止在跳转过程中中断干扰产生异常
    JumpToApp();
    __enable_irq();  //理论上不会到这里
}

APP处理

APP代码中需要进行两个步骤:
1、中断向量表重映射
2、bootloader中已经关闭了总中断,需要重新打开总中断

原理:
对于内嵌flash的MCU中,初始中断向量表一般会被要求固定到flash的起始位置,系统启动之后总是从flash的起始地址获取初始栈地址和初始PC来开始应用程序代码的执行。ARM内核的中断向量表地址默认是0x00000000,这个地址是对应bootloader里面的中断向量表,如果在APP中没有对中断向量表进行重定向的话,那么中断发生的时候进入的僵尸bootloader的中断函数。APP程序是从0x10000开始的,程序起始的最开始的4个地址便是中断向量表的地址,所以需要将中断向量表的地址重定向到0x10000。
在这里插入图片描述

SCB->VTOR = 0x00010000;  //中断向量表重定向

bootloader中的接收升级数据还没有做,未完待续…

  • 42
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值