本帖最后由 wahe2008 于 2018-8-21 08:29 编辑
这是stm32f1xx系列单片机IAP程序到APP程序跳转流程
程序运行的一般过程:
1.程序首先进入中断向表找到中断复位向量,执行复位中断程序即主函数,
2.在主函数中发生中断时,系统强制PC指针指向对应中断向量表对应位置
3.根据中断向量表的中偏移跳转到对应的中断服务程序中,执行相应的中断服务程序
4.相应中断服务程序执行完成后,PC指针跳回发生中断时系统在主函数中的位置,继续往下执行
5.循环执行234步骤
由此可见程序运行的整个过程都在围绕中断向量进行相应的程序执行,所以中断向量表的重要性
要实现单片机从一个程序跳转到另一个程序,我们要做的主要就是更改复位中断向量和中断向量表从而达到
1.中断复位向量指向新的主函数,从而使执行复位中断程序时执行新的主函数即APP的main函数
2.在执行新的主函数时发生中断时,PC指针指向对应新的中断向量表对应位置,执行新的中断服务程序(APP中的中断服务程序)
弄清楚了这个,接下来就是针对不同的单片机来更改复位中断向量和中断向量表来实现我们的目地
对于stm32f1xx系列单片机,
可以修改寄存器SCB->VTOR来设置整个程序的中断向量表的偏移,然后调用JumpToApp函数跳转到新的复位中断向量执行我们APP的主程序
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{
/* Check the parameters */
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}
void JumpToApp(void)
{
ApplicationAddress = APP_FLASHADDR;
if (((*(uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
m_JumpAddress = *(uint32_t*) (ApplicationAddress + 4);
JumpToApplication = (FunVoidType) m_JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(uint32_t*) ApplicationAddress);
JumpToApplication();
}
}
对于stm32f0xx系列单片机,M0并没有SCB->VTOR这个寄存器,但M0增加了个系统配置寄存器(SYSCFG)
我们用以下两行程序来实现M3中NVIC_SetVectorTable函数的功能
把APP的中断向量表拷贝到RAM中(只需要在应用程序中保留RAM起始地址的0xC0大小不使用即可)
memcpy((void*)0x20000000, (void*)APP_FLASHADDR, 0xC0);//
SYSCFG->CFGR1 |= 0x03;//
对于nrf51822单片机,也是M0内核的,不仅没有SCB寄存器,也没有SYSCFG寄存器,那这个单片机要实现中断向量表的新的指向,该如何操作呢?
用类似于stm32f0xx的方法测试多次均没有成功,请高手指点一下
...
|