when jumping from bootloader to application the mcu stucks sometimes
MCU: STM32F411CEU6
So, I am having a weird issue. I created a bootloader for my application to accommodate OTA updates. Bootloader makes decision when it has new firmware inside external flash(the application code tells it), then bootloader loads that otherwise it simply jumps to existing firmware in internal flash. Now issue arise when it jumps to firmware for example I have simply given the command to my application code to reset the mcu, now the mcu goes to bootloader first and then bootloader makes the jump to the firmware in this the jump is successful sometimes and most of the time it fails and the mcu get stuck, and sometimes it keeps working perfectly
now when I send the new firmware to application code it saves it into external flash and then resets it, the bootloader reads special header and so it knows that it needs to download new firmware to the mcu, so instead of jumping to internal flash firmware it erases it and loads the new firmware from external flash and then jumps to it, the success rate for this which I tested is almost 100per and the mcu never get stucks and always successfully goes to new firmware.
The issue only arises if application resets the mcu and most of the time the bootloader fails to jump.
Here is my bootloader code
void flash_jump_to_app(uint32_t address)
{
/* Function pointer to the address of the user application. */
fnc_ptr jump_to_app;
jump_to_app = (fnc_ptr)(*(volatile uint32_t*) (address+4u));
HAL_DeInit();
HAL_RCC_DeInit();
/* Change the main stack pointer. */
__set_MSP(*(volatile uint32_t*)address);
jump_to_app();
}
void app_main()
{
imghdr_t *ipFlaPar;
ipFlaPar = (imghdr_t*) Img_Hdr_Start_Address_Internal_Flash;
/*first we read if external flash has valid image */
SPIF_ReadAddress(&handle_ext_flash,Img_Start_Address_External_Flash,(uint8_t *)&imgFixedhdr,sizeof(imghdr_t));
if(imgFixedhdr.imgVld == Img_Header_valid_bytes )
{
/*now we read the external header in external flash to judge if this image needs to be copied into flash*/
SPIF_ReadSector(&handle_ext_flash, Img_Header_Start_Sector, (uint8_t *)&imgExternalhdr, sizeof(imghdr_t), 0);
if(imgExternalhdr.imgVld == Img_Header_valid_bytes)
{
if(imgExternalhdr.imgCpStat == 1) //needs copy
{
if(copy_img_external_to_internal(&handle_ext_flash,imgExternalhdr.imgExternalStartAdr
,imgExternalhdr.imgHdrStartAdr,imgExternalhdr.imgtotalsize,1024) == 1)
{
imgExternalhdr.imgCpStat = 0; //tell bootloader valid image and copy it
//imgExternalhdr.restartCount = imgExternalhdr.restartCount + 1;
SPIF_EraseSector(&handle_ext_flash, Img_Header_Start_Sector);
SPIF_WriteSector(&handle_ext_flash, Img_Header_Start_Sector, (uint8_t *)&imgExternalhdr, sizeof(imghdr_t), 0);
flash_jump_to_app(imgExternalhdr.prgEntry);
}
}
}
}
/*This tells us there is already an image in internal flash */
if(ipFlaPar->imgVld == Img_Header_valid_bytes )
{
flash_jump_to_app(ipFlaPar->prgEntry);
}
while(1);
}
