在gd32f427 时跳转异常
参考文章:
https://club.rt-thread.org/ask/question/425321.html%20https:/club.rt-thread.org/ask/question/eab19452583b5959.html
https://club.rt-thread.org/ask/question/eab19452583b5959.html
关闭全部中断,并且清除中断标志位,防止有的中断存在中断挂起状态;
对于STM32芯片,如果使用HAL库,则调用HAL_DeInit 和 HAL_RCC_DeInit即可。
如果bootloader程序使用操作系统,在设置栈指针时需要注意当前使用的指针时MSP还是PSP,有PSP切换到MSP可以通过触发SVC异常,就相当于进行一次上下文切换,只不过切换到的是APP程序而不是下一个任务。【还没有做过,先记录一下,有机会再实践一下】
如果当前处在特权模式下,可以直接使用__set_CONTROL(0)实现PSP到MSP的切换。
使用M4芯片时栈顶地址和M3可能不一样,
if (((*(volatile uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000) /* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */
if (((*(volatile uint32_t *)appxaddr) & 0x2FF00000) == 0x20000000) /* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */
typedef void (*app_func_t)(void);
uint32_t app_addr = appxaddr;
uint32_t skt_addr = *((__IO uint32_t*)app_addr);
app_func_t app_func = (app_func_t)(*((__IO uint32_t*)(app_addr+4)));
if ((((uint32_t)app_func & 0xff000000) != 0x08000000) || ((skt_addr & 0x2ff00000) !=0x20000000))
{
App_IapLoadAppret = -1;
return;
}
HAL_Delay(100);
__disable_irq();
HAL_DeInit();
for(int i = 0; i < 128; ++i)
{
HAL_NVIC_DisableIRQ(i);
HAL_NVIC_ClearPendingIRQ(i);
}
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
HAL_RCC_DeInit();
__set_CONTROL(0);
__set_MSP(skt_addr);
app_func();