关于IAP跳转部分的代码的理解

第一句:

if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)   //推断栈定地址值是否在0x2000 0000 - 0x 2000 2000之间

怎么理解呢?

(1)在程序里  #define ApplicationAddress  0x08004800 ,*(__IO uint32_t*)ApplicationAddress)  即取0x08004800開始到0x080048003 的4个字节的值, 由于我们的应用程序APP中设置把 中断向量表 放置在0x08004800 開始的位置;而中断向量表里第一个放的就是栈顶地址的值

也就是说,这句话即通过推断栈顶地址值是否正确(是否在0x2000 0000 - 0x 2000 2000之间) 来推断是否应用程序已经下载了,由于应用程序的启动文件刚開始就去初始化化栈空间,假设栈顶值对了,说应用程已经下载了启动文件的初始化也运行了;

第二句:   

 JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);   [  common.c文件第18行定义了:  pFunction   Jump_To_Application;]
                      

ApplicationAddress + 4  即为0x0800 3004 ,里面放的是中断向量表的第二项“复位地址”  JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); 之后此时JumpAddress

第三句:  

Jump_To_Application = (pFunction) JumpAddress;

startup_stm32f10x_md_lv. 文件里别名  typedef  void (*pFunction)(void);     这个看上去有点奇怪;正常第一个整型变量   typedef  int  a;  就是给整型定义一个别名 a

 void (*pFunction)(void);   是声明一个函数指针,加上一个typedef 之后  pFunction仅仅只是是类型 void (*)(void) 的一个别名

所以,Jump_To_Application = (pFunction) JumpAddress;  此时Jump_To_Application指向了复位函数所在的地址;

第四 、五句: 

__set_MSP(*(__IO uint32_t*) ApplicationAddress);      \\设置主函数栈指针
               Jump_To_Application();                         \\运行复位函数

Jump_To_Application()是把用户代码的复位地址付给PC指针,我看到Jump_To_Application()这句代码debug的时候相应的汇编代码是

LDR r0,[pc,#12] ;相对PC的数据载入,去函数指针的地址
LDR r0,[r0,#00] ;R0做索引,无偏移,数据装载到R0,这个内容就是函数指针指向的内容,也就是函数的地址了,用户程序的起始地址;
BLX r0              ;这个不解释,说了是跳转

APP中配置处理

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后,第一时间先将中断向量表的地址重新映射,再使能全局中断,就可以正常运行了。

参考:

https://zhuanlan.zhihu.com/p/105109753?utm_psn=1781787866303549440icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/105109753?utm_psn=1781787866303549440

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值