会是什么原因void APROM_JumpTo(uint32_t u32TargetAddr){
uint32_t JumpAddress;
pFunction Jump_To_Application;
// 1. 檢查目標地址的堆疊指標 (SP) 是否合法 (M031 的 SRAM 起始於 0x2000_0000)
// 目標地址的第一個字組 (4字節) 存放的是該程式的初始 SP 地址
if (((*(__IO uint32_t*)u32TargetAddr) & 0x2FFF0000 ) == 0x20000000)
{
// 2. 關閉全域中斷(極度重要!防止在跳轉過程中觸發舊程式的中斷導致跑飛)
__disable_irq();
// 3. 關閉系統滴答定時器 (SysTick) 以及所有已開啟的周邊中斷
SysTick->CTRL = 0;
for(int i=0;i<8;i++)
{
NVIC->ICER[i = 0xFFFFFFFF;
NVIC->ICPR[i = 0xFFFFFFFF;
}
SYS_UnlockReg();
FMC_Open();
FMC_SetVectorPageAddr(APP_START_ADDR);
FMC_Close();
SYS_LockReg();
__DSB();
__ISB();
// 4. 取得目標程式的重置向量地址 (目標地址往後移 4 位元組存放的是 Reset_Handler 的 PC 地址)
JumpAddress = *(__IO uint32_t*) (u32TargetAddr + 4);
Jump_To_Application = (pFunction) JumpAddress;
// 5. 初始化目標程式的堆疊指標 (將頂層堆疊指標寫入主堆疊指標暫存器 MSP)
__set_MSP(*(__IO uint32_t*) u32TargetAddr);
// 6. 正式跳轉進目標程式
Jump_To_Application();
}
else
{
// 如果地址非法(例如該區域全是 0xFF,代表沒有燒錄程式),可以在此執行重啟或停留
// printf("Target address is empty or invalid!\n");
while(1);
}
}
|