[C] 纯文本查看 复制代码 //板卡IAP跳转到APP
ERROR_SUB BoardIapJumpApp(void)
{
ERROR_SUB errorSub = ERROR_SUB_OK;
uint32_t app_address = MCU_FLASH_APP;
//首先检测APP是否存在
uint32_t stackPointAddr = ((*(volatile uint32_t*)app_address)&0xF0000000);
//检查栈顶地址是否合法.D1_DTCMRAM_BASE是DTCM的起始地址,也是程序的栈顶地址
//如果这个位置的数据不对,那么说明没有APP
if(stackPointAddr != D1_DTCMRAM_BASE)
{
MCU_LogPrintf("BoardIapJumpApp App stackPointAddr: 0X%08X,Need 0X%08X\r\n",stackPointAddr,D1_DTCMRAM_BASE);
//不存在APP程序,设置失败并设置运行模式是BOOT模式
errorSub = BoardParamSetRunningModeBoot();
return errorSub;
}
//系统运行模式修改为APP模式
errorSub = BoardParamSetRunningModeApp();
if(errorSub != ERROR_SUB_OK)
{
MCU_LogPrintf("BoardParamSetRunningModeApp Failed,ErrorSub: 0X%08X\r\n",errorSub);
return errorSub;
}
//存在APP而且可以跳转
MCU_LogPrintf("BoardIapJumpApp Start\r\n");
CoreDelayMs(10);
//系统锁定
lastBoardIapGlobalIntState = CoreLockIntGlobal();
//清除系统全部中断
CoreClearSystemAllInt();
//获取当前中断向量偏移
vtorBoardIapCurrent = SCB->VTOR;
//设置新的中断向量
SCB->VTOR = app_address;
//获取线程PSP
pspBoardIapCurrent = __get_PSP();
//设置线程PSP
__set_PSP(*(uint32_t*)app_address);
//强制切换到特权级
__set_CONTROL(0);
//获取主堆栈MSP
mspBoardIapCurrent = __get_MSP();
//设置主堆栈MSP
__set_MSP(*(uint32_t*)app_address);
//系统刷新,保证设置生效
__ISB();
//强制跳转
((BoardIapJmpAddressFuncPtr)(*(uint32_t*)(app_address + 4)))();
//到这里,应该执行不下去了,如果执行到这里,需要修复系统运行时环境
SCB->VTOR = vtorBoardIapCurrent;
//设置MSP,现在还是特权模式
__set_MSP(mspBoardIapCurrent);
//退出特权模式
__set_CONTROL(1);
//设置PSP,现在是线程模式了
__set_PSP(pspBoardIapCurrent);
//系统刷新,保证设置生效
__ISB();
//解锁
CoreUnlockIntGlobal(lastBoardIapGlobalIntState);
//报错
MCU_LogPrintf("BoardIapJumpApp Failed\r\n");
CoreDelayMs(10);
//跳转失败,系统运行模式修改为BOOT模式
errorSub = BoardParamSetRunningModeBoot();
if(errorSub != ERROR_SUB_OK)
{
MCU_LogPrintf("BoardParamSetRunningModeBoot Failed,ErrorSub: 0X%08X\r\n",errorSub);
return errorSub;
}
return ERROR_SUB_BOARD_IAP_JMP_APP_FAILED;
} |