Bootloader跳转代码解析

static void Boot_vJumpToApp(uint32_t u32_appAddress) 
{
    uint32_t u32_jumpAddress;
    pFunction JumpToApp;
    
    if (((*(__IO uint32_t*)u32_appAddress) & 0x2FFE0000 ) == 0x20000000) 
    {  
        u32_jumpAddress = *(__IO uint32_t*) (u32_appAddress + 4);  
        JumpToApp = (pFunction)u32_jumpAddress;  
        __set_MSP(*(__IO uint32_t*)u32_appAddress);  
        JumpToApp();
    } 
}

这是一段从Boot跳转到App的代码。

1. ARM Cortex-M 处理器的启动机制

在 ARM Cortex-M 系列处理器中,向量表(Vector Table)是程序启动的核心数据结构。向量表的前两个条目分别是:

  1. 初始主栈指针(MSP):处理器上电后,第一个从向量表加载的值,用于初始化栈顶地址。
  2. 复位向量(Reset Handler):第二个值,指向应用程序的入口函数(即 main 函数之前的初始化代码)。

当处理器复位或跳转到应用程序时,硬件会自动完成以下操作:

  • 将向量表的第一个值(MSP)加载到栈指针寄存器(SP)。
  • 将第二个值(复位向量)加载到程序计数器(PC),开始执行应用程序。

2. 代码逻辑分析

  1. 条件检查

    if (((*(__IO uint32_t*)u32_appAddress) & 0x2FFE0000 ) == 0x20000000)
    • 目的:验证应用程序的初始栈指针(MSP)是否有效。
    • 操作
      • u32_appAddress 是应用程序的起始地址,通常指向应用程序的向量表。
      • 读取 u32_appAddress 处的第一个32位值(即应用程序的初始栈指针,这里取出的数值是应用程序的MSP初始值)。
      • 使用掩码 0x2FFE0000 过滤无关位,检查结果是否为 0x20000000(典型RAM起始地址)。
    • 意义:确保栈指针指向有效的RAM区域,避免跳转到非法地址。
  2. 获取应用程序入口地址

    u32_jumpAddress = *(__IO uint32_t*) (u32_appAddress + 4);
    • 目的:获取应用程序的复位向量(Reset Handler)。
    • 操作
      • u32_appAddress + 4 是向量表的第二个条目,存储应用程序的入口地址。
      • 读取该地址的值,即应用程序的入口函数指针。
  3. 函数指针转换

    JumpToApp = (pFunction)u32_jumpAddress;
    • 目的:将入口地址转换为可调用的函数指针。
    • 说明pFunction 通常定义为 typedef void (*pFunction)(void),即无参数无返回的函数指针类型。
  4. 设置主栈指针(MSP)

    __set_MSP(*(__IO uint32_t*)u32_appAddress);
    • 目的:将栈指针切换到应用程序的初始栈。
    • 操作:通过 __set_MSP 函数(通常为内联汇编或CMSIS函数)设置MSP为应用程序的栈顶。
  5. 跳转到应用程序

    JumpToApp();
    • 目的:执行应用程序的入口函数。
    • 效果:程序计数器(PC)指向应用程序的复位处理函数,完成控制权转移。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值