在使用qboot建立bootloader的时候,发现跳转到app后app死机。
查阅很多资料均说是中断没有关干净导致,但是我检查了一遍也没发现。
于是我新建了两个最基础的rtthread工程,一个加上跳转函数作为bootloader,一个在main.c中添加中断向量表偏移函数作为app,但是就这样的组合,跳转还是出现了hardfault,调试可发现其跳转至app,在hw_board_init中,clk_init前开启总中断,执行后就会触发systick中断,随后就hardfault了,但是这个systick中断在bootloader中跳转前已经关闭,跳转函数还是使用的qboot的跳转函数。
我也查阅了很多资料,我怀疑是pendsv搞的鬼,但是我调试时在pendsv处打断点,也没发现进pendsv中断,所以就很困惑。还望有经验的大神指导指导。
rtthread为4.03版本。
bootloader 跳转函数
RT_WEAK void qbt_jump_to_app(const char*part)
{
typedef void (*app_func_t)(void);
rt_uint32_t app_addr = BOOT_APP_ADDR;
rt_uint32_t stk_addr = *((__IO uint32_t *)app_addr);
app_func_t app_func = (app_func_t)(*((__IO uint32_t *)(app_addr + 4)));
if(partInvalid(part, BOOT_APP_ADDR) == RT_TRUE){
return;
}
LOG_I("Jump to application(%s) 0x%08x 0x%08x running ... ", part,stk_addr,(uint32_t)app_func);
rt_thread_mdelay(200);
__disable_irq();
HAL_DeInit();
for(int i=0; i<128; i++)
{
HAL_NVIC_DisableIRQ(i);
HAL_NVIC_ClearPendingIRQ(i);
}
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
HAL_RCC_DeInit();
__set_CONTROL(0);
__set_MSP(stk_addr);
app_func();//Jump to application running
LOG_E("Qboot jump to application fail.");
}
app
/**
* Function ota_app_vtor_reconfig
* Description Set Vector Table base location to the start addr of app(RT_APP_PART_ADDR).
*/
static int ota_app_vtor_reconfig(void)
{
#define NVIC_VTOR_MASK 0x3FFFFF80
/* Set the Vector Table base location by user application firmware definition */
SCB->VTOR = RT_APP_PART_ADDR & NVIC_VTOR_MASK;
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
@红枫
请大佬看看是不是这个道理😐
赞!你的改动可以向仓库发个PR。
这样boot是否太慢了?不过boot里面配了PLL后,APP里面再配PLL时顺序非常重要,不然容易死锁,所以boot中deinit了。
复位之前,可以向这个寄存器里写值清除SysTick的Pending标志。
@JonasWen
嗯嗯 这样是更保险了