bootloader跳转APP注意事项

在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) */
bootloader跳转APP注意事项_第1张图片

  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();

你可能感兴趣的:(单片机)