BootLoader升级完成后,要想正确完成跳转,有3部分工作需要完成。1、跳转到新的程序地址执行程序;2、重新设置新程序的堆栈首地址;3、重新设置中断向量表。结合下图说明如下: 新程序的下载地址就是下图的首地址,
Initial SP value对应的实际地址是首地址+0,Reset对应的实际地址是首地址+4。Initial SP value里面的值是重新设置的堆栈首地址;Reset里面的值是新程序的执行地址。 #define USER_DEFINE_RUN_ADDR 0x5000方式一:c语言配合寄存器 1、设置新的PC指向,需要放在bootloader里面
typedef OS_S32 (*PM3EntryFunc)(OS_VOID); /* 定义一个新的函数指针类型,和新程序的main类型相同 */
PM3EntryFunc pfJumpToApp = NULL; /* 定义一个函数指针变量 */
OS_U32 g_u32JumpAddress = 0; /* 保存地址 */ g_u32JumpAddress = *( OS_U32*) (USER_DEFINE_RUN_ADDR + 4);
pfJumpToApp = (PM3EntryFunc)g_u32JumpAddress;
pfJumpToApp(); 2、设置新的中断向量:
SCB->VTOR = USER_DEFINE_RUN_ADDR;
3、设置新的堆栈地址 __set_MSP(*(OS_U32*) USER_DEFINE_RUN_ADDR);
方式二:嵌入式汇编配合寄存器 1、重新设置堆栈和跳转指针,需要传入新程序的下载地址
__ASM void StartApplication(uint32_t start_addr)
{
LDR R2, [R0] ;// Get App MSP.
MSR MSP, R2 ;// Set the main stack pointer to the applications MSP. 设置堆栈指针
LDR R3, [R0, #0x00000004] ;// Get application reset vector address. 设置跳转地址
BX R3 ;// No return - stack code is now activated only through SVC and plain interrupts.
ALIGN
} StartApplication(USER_DEFINE_RUN_ADDR);
2、设置新的中断向量:
SCB->VTOR = USER_DEFINE_RUN_ADDR;