in lib/bootloader/spifi_boot.c [279:394]
int32_t boot_run(void)
{
struct boot_ucb ucb;
void *exec_image = (void *)BOOT_EXEC_IMAGE_ADDR;
PRINTF("\r\nSPIFI bootloader " BOOT_VERSION_STRING "\r\n");
/* load update control block */
boot_ucb_read(&ucb);
/* update control block is present, process it */
switch (ucb.state)
{
case BOOT_STATE_UNDEF:
case BOOT_STATE_VOID:
/* nothing to do be done */
break;
case BOOT_STATE_NEW:
/* new update image available, flash it and switch to test mode */
if (0 != boot_image_validate(ucb.update_img))
{
/* the update image is invalid, erase the update control block and execute the current image */
PRINTF(BOOT_PROMPT_STRING "Invalid update image!\r\n");
ucb.state = BOOT_STATE_VOID;
}
else
{
PRINTF(BOOT_PROMPT_STRING "Installing update... ");
if (boot_image_copy((void *)BOOT_EXEC_IMAGE_ADDR, ucb.update_img) > 0)
{
PRINTF("OK\r\n");
ucb.state = BOOT_STATE_PENDING_COMMIT;
}
else
{
PRINTF("ERROR\r\n");
exec_image = NULL; /* the current image might be corrupted */
ucb.state = BOOT_STATE_INVALID; /* set state to invalid to got for rollback upon next boot */
}
}
if (boot_ucb_write(&ucb) != 0)
{
PRINTF(BOOT_PROMPT_STRING "ERROR writing update control block\r\n");
}
break;
/* reboot from test mode or image explicitly rejected, rollback */
case BOOT_STATE_PENDING_COMMIT:
case BOOT_STATE_INVALID:
if (0 != boot_image_validate(ucb.rollback_img))
{
/* the rollback image is invalid, just try executing the current one as last resort solution */
PRINTF(BOOT_PROMPT_STRING "No rollback image, executing the current one... ");
ucb.state = BOOT_STATE_VOID;
}
else
{
PRINTF(BOOT_PROMPT_STRING "Rolling back to previous image... ");
if (boot_image_copy((void *)BOOT_EXEC_IMAGE_ADDR, ucb.rollback_img) > 0)
{
PRINTF("OK\r\n");
ucb.state = BOOT_STATE_VOID;
}
else
{
/* flashing failed, set state to invalid to go for rollback upon next boot */
PRINTF("ERROR\r\n");
exec_image = NULL; /* the current image might be corrupted */
ucb.state = BOOT_STATE_VOID; /* as the state is void, next reboot would attempt to execute whatever is there */
break;
}
}
if (boot_ucb_write(&ucb) != 0)
{
PRINTF(BOOT_PROMPT_STRING "ERROR writing update control block\r\n");
}
break;
/* any other state should result in erasing the update control block */
default:
PRINTF(BOOT_PROMPT_STRING "Unexpected state, erasing update control block... ");
if (boot_ucb_erase() == 0)
{
PRINTF("OK\r\n");
}
else
{
PRINTF("ERROR\r\n");
}
break;
}
DbgConsole_Flush();
if (exec_image != NULL)
{
PRINTF(BOOT_PROMPT_STRING "About to execute application...\r\n");
if (ucb.state == BOOT_STATE_PENDING_COMMIT)
{
/* enable watchdog */
PRINTF(BOOT_PROMPT_STRING "Enabling watchdog...\r\n");
boot_wdten();
}
boot_app_exec((void *)BOOT_EXEC_IMAGE_ADDR);
PRINTF(BOOT_PROMPT_STRING "Application exec failed.\r\n");
}
else
{
PRINTF(BOOT_PROMPT_STRING "No valid image to boot.\r\n");
}
DbgConsole_Flush();
return -1;
}