最近在做bootloader引导app时发现如果APP有操作系统时,会引导不起来,现象如下:
平台:stm32H743 采用stm32cubemx配置的HAL库
测试方式:上电后运行boot loader,bootloader是裸机运行。由bootloader引导第一段APP,此app由freertos。再通过第一段app运行第二段app,此app也由freertos.
1.由bootloader引导第一段APP
1)怀疑是bootloader用sd卡导致的(屏蔽sd卡时可正常引导)。
2)引导起来后,会死循环再定时器中。用的hal库,里面hal_delay延时用的tim16改为其他定时器后可用,我改的tim2。怀疑是两个程序不能用统一个定时器作为hal_delay的定时
3)引导时关闭所有中断
引导代码
void Close_All_IRQ(void)
{
int i;
/* 关闭全局中断 */
__set_PRIMASK(1) ;
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 设置所有时钟到默认状态, 使用 HSI 时钟 */
HAL_RCC_DeInit();
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
/* 使能全局中断 */
__set_PRIMASK(0) ;
}
void iap_load_app(u32 appxaddr)
{
Close_All_IRQ();
__HAL_RCC_SDMMC1_CLK_DISABLE();
if(((*(vu32*)appxaddr)&0x2FF00000)==0x24000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.
}
}
2.第一个APP引导第二个APP
1)更换第二个APP的HAL_Delay的定时器,需要跟第一个APP不同
2)由于使用了实时操作系统,需要增加__set_CONTROL(0);引导
引导代码:
void iap_load_app(u32 appxaddr)
{
Close_All_IRQ();
__HAL_RCC_SDMMC1_CLK_DISABLE();
if(((*(vu32*)appxaddr)&0x2FF00000)==0x24000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
__set_CONTROL(0);
jump2app(); //跳转到APP.
}
}
至此,可正常引导两个程序