单片机远程升级(IAP)和中断跳转补充

单片机BootLoader远程升级(IAP)和中断跳转补充

本文作为上一个文章的补充,主要对中断跳转和执行进行补充说明,实现完整的bootloader跳转功能

中断跳转

我们在上一篇文章中实现了一个简单的程序跳转功能,使用一个函数指针从编写的简易的Bootloader跳转到了点亮LED的APP去,这两个程序的执行文件内容大致如下图所示。但是关于程序的执行流程讲的不是很详细,在此进行补充。

请添加图片描述请添加图片描述

在上一篇文章中,我们说明了中断向量表中Reset_Handler的作用,那么当系统触发其他中断时会怎样呢?首先我们先了解一下单片机触发中断时的流程,单片机上电后运行程序,此时触发外部中断0,堆栈保存当前的程序位置,然后单片机会到中断向量表中查找存放的服务函数地址,查找到后会跳转至这个地址,运行中断服务函数,中断结束后退出中断,从堆栈中取出原来运行的位置,继续回到主程序运行。请添加图片描述

请添加图片描述

由于单片机默认会从执行文件最前端的中断向量表中查找中断地址,那么如果在APP中触发中断,那么单片机也会跳转至第一个中断向量表进行查找,然后跳转至对应中断,由于此时的程序是运行在APP区的,而跳转到的中断函数是Boot区的,那么单片机就会运行Boot区的中断函数,然后再跳转回APP,这也就会导致芯片中断异常,即APP区的中断毫无作用甚至导致芯片死机,我们可以在中断函数中加入中断跳转功能,当系统进入Boot区运行中断函数时,我们可以通过函数指针,将指针地址设定为APP区中断向量表中对应的位置,再运行指针函数,那么就在Boot区运行了APP区中断,也就通过中断跳转间接的实现了APP区的中断,流程如下图所示。

跳转函数与之前的一样,都是创建一个函数指针,然后将指针地址改为向量表地址,运行指针函数即可,正常来说我们应该跳转至中断服务程序的入口,但是中断服务函数的地址是位置的,而中断服务函数的位置在向量表中是固定的,并且向量表在执行文件中的位置是已知的,那么我们就可以通过先跳转到向量表查询地址,再执行对应的中断,中断跳转函数如下。

 void FuntionJump(u08 Num)
{
    void (*pFunction)(void);
    u32 address;
    McuFlashByteRead((u08*)(&address), APP_CODE_ROM_OFFSET+SCOFFSET+4*Num,4); 
    pFunction = (void (*)(void))address;	
    pFunction();
}

堆栈指针初始化

ARM系列单片机中有堆栈指针SP和程序计数器PC,PC用于存放当前运行的程序(指令)地址,SP为堆栈指针,指向当前使用的RAM中存储的程序地址,一般来说SP、PC和执行这三个应该步调一致,就像鞋子,袜子和脚的关系一样。PC取指令,SP装入指针,然后芯片执行指令,但是从Boot跳转到APP的时候,我们相当于对芯片进行了一次复位,让芯片从“头”开始运行,但是此时SP的指针仍然是Boot的,而PC中的指令已经是APP区的指令了,就仿佛迈出一步后脚和袜子一起动了,鞋还留在原地一样。单片机没见过这种场面,所以会直接懵掉,然后死机复位。那么为了解决这个问题,就需要在跳转的时候对SP进行初始化,将Boot的SP指针变成APP的,这个时候我们就用到了__set_MSP这个函数,通过这句话我们就可以将SP设置为基于APP区的起始地址的了,实现了SP的初始化和跳转,这样SP就指向了APP区的首地址,APP程序也就可以正常运行了。

__set_MSP(* ( __IO uint32_t * )(APPLICATION_ADDRESS + SCOFFSET));
  void (*pFunction)(void);
  __set_MSP(* ( __IO uint32_t * )(APPLICATION_ADDRESS + SCOFFSET));
  pFunction = (void (*)(void))(* ( __IO uint32_t * )(APPLICATION_ADDRESS + SCOFFSET + 4));    
  pFunction();
  return ;  
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值