Bootloader

本文详细解释了Bootloader如何通过检查栈顶地址的有效性并管理中断来确保安全地跳转到应用程序。它涉及栈指针验证、全局中断控制和中断向量表的重映射等关键步骤。
摘要由CSDN通过智能技术生成

Bootloader跳转到APP的代码解析

#define APP_ADDRESS   0X08005000  //为APP的起始地址,需要与工程配置中的起始地址一致
typedef void (*pFunction)(void);
static pFunction s_jumpToApp;  //跳转指针
void JumpToApp(void)
{
        uint32_t JumpAddress;
        
        if(((*(__IO uint32_t *)APP_ADDRESS) & 0x2FFE0000) == 0x20000000)  //判断栈顶指针内容是否有效(指向RAM)
        {
                __ASM("CPSID I");//关全局中断
                JumpAddress = *(__IO uint32_t *)(APP_ADDRESS + 4); //取复位中断向量的值
                s_jumpToApp = (pFunction)JumpAddress;
                __set_MSP(*(__IO uint32_t*)APP_ADDRESS);//设置主函数栈指针
                s_jumpToApp(); //执行复位函数
        }
}

第一句: if(((*(__IO uint32_t *)APP_ADDRESS) & 0x2FFE0000) == 0x20000000)
1.这句是判断栈顶地址值是否在0X20000000~0X20020000之间。APP_ADDRESS通过宏定义为0X08005000,即APP的起始地址。


2.(*(__IO uint32_t *)APP_ADDRESS),即取 0X08005000~0X08005003的4个字节的值。因为应用程序APP中设置把中断向量表放在0X08005000开始的位置,而中断向量表里第一个放的就是栈顶地址的值。即这里取出了栈顶地址的值。


3.堆栈指针(SP)必须在SRAM中,SRAM的地址范围都是从0X20000000处开始的,128K的SRAM的地址范围是0X20000000~0X2001FFFF。当APP运行的程序栈顶指针落在SRAM区域时,这个时候就是有效的栈顶指针。


4.也就是说,这句代码通过判断栈顶地址值是否正确(是否在0x20000000~0x2001FFFF之间)来判断是否应用程序已经下载了,因为应用程序的启动文件刚开始就去初始化栈空间。如果栈顶指针对了,说明应用程序已经下载了,启动文件的初始化也执行了,就可以进行跳转。


5.128K的SRAM是比较大的了,用&0x2FFE0000就能覆盖大部分SRAM了,也可以根据实际的SRAM大小修改。


第二句:__ASM("CPSID I")
这句是关掉全局中断。跳转前最好将中断关掉,以防中断向量表还没映射导致程序跑飞。


第三句:JumpAddress = *(__IO uint32_t *)(APP_ADDRESS + 4)
1.这句是取复位中断向量的值
2. (APP_ADDRESS+4)即为0x08005004,里面放的是中断向量表的第二项“复位地址”,执行完完该句后,将复位中断的中断函数地址赋值给JumpAddress。


第四句:s_jumpToApp = (pFunction)JumpAddress
1.这句的意思是将上一句取得的中断函数地址转为函数指针。void (*pFunction)(void);是声明了一个函数指针。
2.此时,s_jumpToApp指向了复位中断函数所在的地址。


第五句:__set_MSP(*(__IO uint32_t*)APP_ADDRESS)
1.这句是设置主函数栈指针
2.__set_MSP,该函数的功能就是设置主栈指针。


第六句:s_jumpToApp()
执行复位函数,跳转到APP运行。


三、APP中配置处理
在APP中,进入main函数,首先应该重映射向量表,再使能全局中断。
int main(void)
{
    SCB->VTOR = APP_ADDRESS;    //重映射向量表
    __ASM("CPSIE I");           //使能全局中断
   
   /*用户代码 */
    GPIO_Config();
    TIMER_Config(1000);

    while(1)
    {
                        
    }
}
VTOR寄存器存放的是中断向量表的起始地址。对于APP,设置为flash基址+偏移量,即0X08005000,所以需要在APP的main函数最开头处添加SCB->VTOR = APP_ADDRESS,实现中断向量表的起始地址的重设。


四、跳转时对中断的处理
     ARM芯片可以实现多个APP,通过boot来控制APP,通过不同的地址选择跳转到不同的APP。
     常用的为Bootloader跳转到APP,若要实现逆向跳转,通过复位即可实现,因为复位后程序会从flash最开始处执行,即bootloader.
     每个APP包括boot loader都有各自的中断向量表,若在相应代码中有使用中断,跳转前需先关闭中断,以免刚跳转过去还没来得及重新设置中断向量表就产生中断,找不到中断入口和执行函数,程序跑飞。
     跳转到APP后,第一时间先将中断向量表的地址重新映射,再使能全局中断,就可以正常运行了。

  • 34
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值