程序升级时跳转到应用程序的方法

2019-04-15 18:31发布

从事单片机工作有几年了,对于单片机程序升级还是接触的不多,看别人写的两个程序,觉得在bootloader里跳转到应用程序方法还是挺不错了,先做下记录,怕以后忘记了。
首先来看看第一个
假设应用程序的入口地址为appadder,
void (*UserProgram)();//定义一个函数指针
UserProgram = (void (*)()) (appadder);   //把应用程序入口地址赋给函数指针
(*UserProgram)();//调用一次函数指针,即跳转到应用程序入口,执行应用程序
这个方法在ARM7中使用没有问题
这里重点要理解指针函数和函数指针,区别的最简单的方法就是看*号是在括号里还是括号外,如果在括号里就是函数指针,就像上面void (*UserProgram)();就是个函数指针,如果是void *UserProgram();他就是个指针函数。

cortex-M3的做法会多一步,不但要初始化NVIC,还要初始化SP指针,因为两者所在的模式不同
定义一个跳转函数
void runApp(unsigned int addr)
{
unsigned int *p = (unsigned int *)addr;
unsigned int sp = *p++;
void (*func)(void) = (void (*)(void))*p;//把应用程序入口地址赋给函数指针
NVIC_DeInit();  //初始化NVIC

__MSR_MSP(sp);//
func();
while(1);
}
1、__MSR_MSP 的实现看 cortexm3_macro.s
2、汇编指令 MSP 的意义看 Cortex-M3 的指令手册
3、sp的含义,就是应用程序中断向量的含义了:偏移0=Initial SP,偏移4=Reset Vector,所以P装载为 addr ,SP装载为addr+4
这么做,相当于仿真了一个复位,只是这个复位后的 SP,PC 分别从目标镜像,也就是 addr开始的单元得到的,而不是真正的物理地址 0 , 另外,如果做得地道的话,应该要配置一下 NVIC 指向新的镜像的中断向量表,这里也做了,只是 ST 的代码一般都自带了 NVIC_Configuration 这么一个函数,所以只要在中断没有打开的情况下,在应用程序里面配置也是可以的,只是这样就和真正的复位相比而言,差了一步