ARM单片机工程之间的切换

ARM单片机工程之间的切换
在做ARM单片机开发的时候 , 有时候会在一个MCU内部存放几个工程 , 工程之间可以是独立的 , 也可以是有联系的 。有联系体现在2个以上的工程公用RAM和flash资源 , 实现工程之间的同步 , 如果单片机内部存在BRAM( RAM) , 那么可以选择使用BRAM存放工程之间的共享数据;如果没有 , 还可以使用读写Flash实现数据的共享 。本章主要介绍ARM单片机中工程之间的跳转 。
1.首先了解下中断向量表
上图摘自芯片手册 , 首先这个中断向量表上可以直观的看到地址存放的是SP的初始值 , 地址存放的是Reset 。可以在IAR或者KEIL调试程序的时候看到 , Reset其实就是一个跳转的地址 , 具体的说是 , 中断向量表上每个单位存放的是4个字节组成的地址 , 当有中断异常等发生时 , 就会认准里面存的地址然后直接跳过去运行 。(目前接触到的M3,M4,M7内核的中断向量表都长这啥样)
2.主堆栈MSP

ARM单片机工程之间的切换

文章插图
MSP:缺省的堆栈指针 , 它由OS内核、异常服务例程以及所有需要特权访问的应用程序代码使用 。在程序启动的时候 , 会将上面中断向量表的SP Value写到MSP 。
3.程序计数器PC
PC , 字面意思就是记录程序的执行位置 , 在程序一启动的时候 , 默认是将Reset的地址赋值给PC , 然后运行代码 。因为Arm内核使用了指令流水线 , 所以在读PC时返回的值是当前指令地址+4 。
4.系统的Reset序列
系统先是进入复位状态 , 接着在离开复位状态后 , 内核做的第一件事:
ARM单片机工程之间的切换

文章插图
(1)从地址处读取MSP的初始值 。
(2)从地址处读取PC的初始值–这个是复位向量 , 最低位LSB必须为1 。程序就是从这PC值真正开始运行的 。
5.跳转代码的书写
下面直接贴出工程跳转函数:
typedef void (*func)();void Project_Jump(uint32_t addr){func func_ptr;SysTick->CTRL = 0;//关闭滴答定时器__disable_irq();//关闭全局中断for(uint8_t i=0;i<8;i++){NVIC->ICER[i] = 0xFFFFFFFF;//可屏蔽中断失能NVIC->ICPR[i] = 0xFFFFFFFF;//解除被挂起的中断}__DSB();__ISB();SCB->VTOR = addr;//设置中断向量表地址__DSB();__ISB();__enable_irq();//使能全局中断__set_MSP(*(uint32_t *)addr);//设置堆栈指针func_ptr = (__IO func)(*(__IO uint32_t*) (addr+4));//指针函数赋值func_ptr();}
【ARM单片机工程之间的切换】上面的__DSB()和__ISB()最好加上 , 确保数据和指令都同步 。还有就是 , 如果单片机当前工程有使用到和的话 , 跳转的时候也需要将它们和Clean掉 。