IAP在线升级二
一.分析JumpToApp函数
点击查看代码
void JumpToApp(uint32_t addr)
{
__disable_irq();//这个函数调用会禁用中断。在跳转到新的应用程序之前,通常需要确保当前的中断状态不会干扰跳转过程。
uint32_t sp = *((volatile uint32_t *)(addr));//从addr指定的地址读取栈指针(Stack Pointer,SP)的值。volatile关键字告诉编译器不要优化这部分代码,因为它可能会在程序执行过程中改变。
uint32_t pc = *((volatile uint32_t *)(addr + 4));//从addr + 4的地址读取程序计数器(Program Counter,PC)的值,这是新应用程序的入口地址。
typedef void (*Func_void_void)(void);
Func_void_void ResetHandler = (Func_void_void)pc;//将pc的值转换为Func_void_void类型的函数指针,并将其赋值给ResetHandler变量。
SCB->VTOR = addr;//设置向量表偏移寄存器(Vector Table Offset Register,VTOR)的值为addr。这个寄存器定义了中断向量表的起始地址。在跳转到新应用程序时,需要更新这个寄存器,以便中断能够正确地跳转到新应用程序的中断处理函数。
__set_MSP(sp);//设置主堆栈指针(Main Stack Pointer,MSP)为从addr读取的栈指针值。这是为了确保新应用程序能够使用正确的堆栈。
ResetHandler();//调用ResetHandler函数,这实际上是跳转到新应用程序的入口点。
while(1) __NOP();//在跳转到新应用程序后,如果函数返回,这将导致程序进入一个无限循环,执行空操作(No Operation,NOP)。这通常是为了防止程序返回到旧的上下文中。
}
#define FLASH_APP1_ADDR 0x00008000
JumpToApp(FLASH_APP1_ADDR);
二.3个核心寄存器
-
1.三级流水线
ARM-CPU属于属于精简指令集,三级流水线。取指、译指、执行。
理想的情况下,保证了每个CPU-Cycle都有一个指令被执行。
ARM指令是三级流水线,取指,译指,执行时同时执行的,现在PC指向的是正在取指的地址。在地址为m的指令时,PC值为m+4,所以PC值总是当前正在执行的指令地址加4。
(注意:当突然发生中断的时候,保存的是PC的地址,如果返回的时候返回PC,那么中间就有一个指令没有执行,所以用SUB pc lr-irq ) -
- SP寄存器(R13):
堆栈指针,SP总是指向栈顶。
SP寄存器分为MSP和PSP。(MSP---主栈指针、默认栈指针;PSP---中断栈指针、进程栈寄存器)。
在裸机模式下,通常只使用MSP,而在操作系统环境下,MSP和PSP会根据任务切换和异常处理动态切换。
- SP寄存器(R13):
-
- LR寄存器(R14):
LR寄存器保存的是,执行子函数、中断、任务切换(中断包括任务切换:xPortPendSVHandler),PC指针应该跳转回去的地方。
- LR寄存器(R14):
-
- PC寄存器(R15):
程序计数器,内部存的值是当前执行到了哪个地址;PC 总是指向“正在取指”的指令,即“PC+4”。
在《Cortex™-M3 Devices Generic User Guide》中关于SP和LR的描述如下图:
- PC寄存器(R15):
三 PC值分析
1.指令集
- ARM指令集:一条指令为4个字节。
- Thumb指令集:一条指令为2个字节。
- Thumb2指令集:中的大部分指令仍然是16位的Thumb指令,但引入了一些额外的32位指令,以提供更高级别的功能和更灵活的操作数寻址模式。
注:cotex-m3、m4都采用thum2指令集
2.PC值
无论处理器处于何种状态,程序计数器R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或者正在“译码”的指令。
将正在执行的指令作为参考点,即当前第1条指令。所以,PC总是指向第3条指令,或者说PC总是指向当前正在执行的指令地址再加2条指令的地址。
处理器处于ARM状态时,每条指令为4个字节,所以PC值为正在执行的指令地址加8字节,即是:
PC值 = 当前程序执行位置 + 8字节
处理器处于Thumb状态时,每条指令为2字节,所以PC值为正在执行的指令地址加4字节,即是:
PC值 = 当前程序执行位置 + 4字节
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通