int32_t boot_run()

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;
}