本人调试工程中,想实现bootloader中读取sd卡是否有升级固件完成iap升级。逻辑如下:
开机进入bootloader→挂载fatfs系统读取sd卡中是否有升级固件→读卡器的App。
工程用stm32cubemx生成,问题现象如下:
1,直接运行App本身,即usb读卡器任务,是能够读取到sd卡,并且在电脑上进行读写操作的。
2,从bootloader跳转到App后,不开启usb设备的初始化,程序也是正常。
3,跳转后开启usb初始化,程序并没有马上卡死。过了大概1-3s后,程序卡死,触发看门狗复位。
4,经过深度的查询后,我发现在跳转app中,只要不执行 f_mount(&fs,(TCHAR const*)SDPath,1);这一条挂载sd卡命令,在后续的App中并不会卡死。
5,在跳转前,我执行了f_mount(NULL,(TCHAR const*)SDPath,1); 和FATFS_UnLinkDriver(SDPath);即取消挂载和注销。
bootloader跳转的程序我贴下方:
if(retSD == 0)
{
//在SD卡挂载文件系统,文件系统挂载时会对SD卡初始化
f_res = f_mount(&fs,(TCHAR const*)SDPath,1);
//读取是否有升级文件
f_res = f_open(&file, "Jarvis Updata.bin", FA_OPEN_EXISTING | FA_READ);
if(f_res == FR_OK)
{
printf("打开升级文件成功\r\n");
f_res = f_read(&file, ReadBuffer, sizeof(ReadBuffer), &fnum);
if(f_res==FR_OK)
{
//这里写升级
HAL_Delay(5000);
}
else
{
printf("升级文件读取失败 错误代码(%d)\r\n",f_res);
delete_updata_sign = 1; //文件错误删除升级固件
}
}
else
{
printf("未检测到升级文件\r\n");
jump_app_sign = 1; //跳转app标志位
}
memset(ReadBuffer,NULL,sizeof(ReadBuffer));
f_close(&file);
if(delete_updata_sign == 1) //如果要删除升级文件
{
f_res = f_unlink("Jarvis Updata.bin");
if(f_res==FR_OK)
{
printf("删除升级文件成功,进入跳转\r\n");
jump_app_sign = 1; //跳转app标志位
}
}
/* 不再使用,取消挂载 */
f_res = f_mount(NULL,(TCHAR const*)SDPath,1);
/* 注销一个FatFS设备:SD卡 */
FATFS_UnLinkDriver(SDPath);
}
if(jump_app_sign == 1)
{
HAL_RCC_DeInit();
HAL_RTC_MspDeInit(&hrtc);
HAL_UART_MspDeInit(&huart1);
HAL_SD_MspDeInit(&hsd);
HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn);
HAL_NVIC_DisableIRQ(DMA2_Stream5_IRQn);
HAL_NVIC_DisableIRQ(DMA2_Stream6_IRQn);
HAL_TIM_Base_MspDeInit(&htim3);
HAL_TIM_Base_MspDeInit(&htim5);
HAL_TIM_Base_MspDeInit(&htim6);
HAL_TIM_Base_MspDeInit(&htim7);
appxaddr = 0x08010000;
jump2app=(iapfun)*(uint32_t*)(appxaddr+4);
__set_MSP(*(uint32_t*)appxaddr);
SCB->VTOR=appxaddr;
__disable_irq();
jump2app();
}
然后App程序里,初始化模板生成的,图片贴如下:
如果程序不进行跳转,直接运行App是能够正常运行并读出卡的,但是只要在bootloader中挂载过,哪怕之后跳转取消了,依然跳转后会卡死在,图片中 MX_USB_DEVICE_Init();执行后,1-3s内。其中sdio用的是DMA,不知道各位有没有遇到过类似的问题,如有雷同问题,还请指导。