Exemplo n.º 1
0
uint32_t bootloader_dfu_sd_update_continue()
{
    uint32_t err_code = NRF_SUCCESS;
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    /* Ignore update attempts on invalid src_image_address */
    if( (p_bootloader_settings->src_image_address == SRC_IMAGE_ADDRESS_EMPTY)   ||
        (p_bootloader_settings->src_image_address == SRC_IMAGE_ADDRESS_INVALID))
    {
        return NRF_SUCCESS;
    }

    if( (p_bootloader_settings->sd_image.st.bank == NEW_IMAGE_BANK_0)           ||
        (p_bootloader_settings->sd_image.st.bank == NEW_IMAGE_BANK_1))
    {
        debugger_delay();

        err_code = dfu_sd_image_swap();
        if (dfu_sd_image_validate() == NRF_SUCCESS)
        {
            /* This is a manual write to flash, non-softdevice managed */
            uint32_t address    = (uint32_t)p_bootloader_settings + BOOTLOADER_SETTINGS_SD_IMAGE_SIZE_ADR_OFFSET;
            temp_value      = p_bootloader_settings->sd_image.all & 0x3FFFFFFF; // clears image bank bits.
            nrf_nvmc_write_word( address, temp_value);
            //TODO need to catch verification error
        }
    }
    return err_code;
}
bool bootloader_app_is_valid(uint32_t app_addr)
{
    const bootloader_settings_t * p_bootloader_settings;

    // There exists an application in CODE region 1.
    if (*((uint32_t *)app_addr) == EMPTY_FLASH_MASK)
    {
        return false;
    }

    bool success = false;

    bootloader_util_settings_get(&p_bootloader_settings);

    // The application in CODE region 1 is flagged as valid during update.
    if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
    {
        uint16_t image_crc = 0;

        // A stored crc value of 0 indicates that CRC checking is not used.
        if (p_bootloader_settings->bank_0_crc != 0)
        {
            image_crc = crc16_compute((uint8_t *)DFU_BANK_0_REGION_START,
                                      p_bootloader_settings->bank_0_size,
                                      NULL);
        }

        success = (image_crc == p_bootloader_settings->bank_0_crc);
    }

    return success;
}
Exemplo n.º 3
0
uint32_t bootloader_dfu_bl_update_continue(void)
{
    uint32_t err_code = NRF_SUCCESS;
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    /* Ignore update attempts on invalid src_image_address */
    if( (p_bootloader_settings->src_image_address == SRC_IMAGE_ADDRESS_EMPTY)   ||
        (p_bootloader_settings->src_image_address == SRC_IMAGE_ADDRESS_INVALID))
    {
        return NRF_SUCCESS;
    }

    if( (p_bootloader_settings->bl_image.st.bank == NEW_IMAGE_BANK_0)           ||
        (p_bootloader_settings->bl_image.st.bank == NEW_IMAGE_BANK_1))
    {
        debugger_delay();

        if (dfu_bl_image_validate() != NRF_SUCCESS)
        {
            err_code = dfu_bl_image_swap(); // reset is built in to the mbr bootloader swap
        }
        else
        {
            /* This is a manual write to flash, non-softdevice managed */
            uint32_t address    = (uint32_t)p_bootloader_settings + BOOTLOADER_SETTINGS_BL_IMAGE_SIZE_ADR_OFFSET;
            uint32_t value      = p_bootloader_settings->bl_image.all & 0x3FFFFFFF; // clears image bank bits.
            err_code            = blocking_flash_word_write((uint32_t *)address, value);
            //TODO need to catch verification error
        }
    }
    return err_code;
}
Exemplo n.º 4
0
uint32_t dfu_ap_image_swap(void)
{
    uint32_t err_code = NRF_SUCCESS;
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    uint32_t ap_image_start = p_bootloader_settings->src_image_address + p_bootloader_settings->sd_image.st.size + p_bootloader_settings->bl_image.st.size;

    if (ap_image_start == CODE_REGION_1_START)
    {
        return NRF_SUCCESS; // no need to do anything since the code is already in the correct place.
    }

    if (p_bootloader_settings->ap_image.st.size != 0)
    {
        if (m_storage_handle_app.block_id == CODE_REGION_1_START)
        {
            // Erase BANK 0.
            err_code = pstorage_raw_clear(&m_storage_handle_app, p_bootloader_settings->ap_image.st.size);

            if (err_code == NRF_SUCCESS)
            {
                err_code = pstorage_raw_store(&m_storage_handle_app, (uint8_t*) m_storage_handle_swap.block_id,p_bootloader_settings->ap_image.st.size, 0);
            }
        }
    }
    return err_code;
}
Exemplo n.º 5
0
uint32_t bootloader_dfu_ap_update_continue(void)
{
    uint32_t err_code = NRF_SUCCESS;
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    /* Ignore update attempts on invalid src_image_address */
    if( (p_bootloader_settings->src_image_address == SRC_IMAGE_ADDRESS_EMPTY)   ||
        (p_bootloader_settings->src_image_address == SRC_IMAGE_ADDRESS_INVALID))
    {
        return NRF_SUCCESS;
    }

    if( (p_bootloader_settings->ap_image.st.bank == NEW_IMAGE_BANK_0)           ||
        (p_bootloader_settings->ap_image.st.bank == NEW_IMAGE_BANK_1))
    {
        /* If updating application only, we can start the copy right now*/
        if ((p_bootloader_settings->sd_image.st.size == NEW_IMAGE_SIZE_EMPTY)   &&
            (p_bootloader_settings->bl_image.st.size == NEW_IMAGE_SIZE_EMPTY))
        {
            err_code = dfu_ap_image_swap();

            dfu_update_status_t update_status = {DFU_UPDATE_AP_SWAPPED, };

            bootloader_dfu_update_process(update_status);

            wait_for_events();
        }
    }
   return err_code;
}
Exemplo n.º 6
0
bool bootloader_app_is_valid(uint32_t app_addr)
{
    const bootloader_settings_t * p_bootloader_settings;

    // There exists an application in CODE region 1.
    if (DFU_BANK_0_REGION_START == EMPTY_FLASH_MASK)
    {
        return false;
    }
    
    bool success = false;
    
    switch (app_addr)
    {
        case DFU_BANK_0_REGION_START:
            bootloader_util_settings_get(&p_bootloader_settings);

            // The application in CODE region 1 is flagged as valid during update.
            if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
            {
                success = true;
            }
            break;
            
        case DFU_BANK_1_REGION_START:
        default:
            break;
    }

    return success;
}
Exemplo n.º 7
0
bool bootloader_app_is_valid(uint32_t app_addr)
{
    const bootloader_settings_t * p_bootloader_settings;

    // Critical flag was not cleared.
    if (*((uint32_t *)BOOT_SETTINGS_PEND_ADDRESS) == BOOT_SETTINGS_PEND_VALUE)
    {
        return false;
    }

    // There exists an application in CODE region 1.
    if (*((uint32_t *) app_addr) == EMPTY_FLASH_MASK)
    {
        return false;
    }

    bootloader_util_settings_get(&p_bootloader_settings);

    // The application in CODE region 1 was not flagged as invalid.
    if (p_bootloader_settings->valid_app == BOOTLOADER_SETTINGS_INVALID_APPLICATION)
    {
        return false;
    }

    return true;
}
void bootloader_dfu_update_process(dfu_update_status_t update_status)
{
    static bootloader_settings_t settings;
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    if (update_status.status_code == DFU_UPDATE_COMPLETE)
    {
        settings.bank_0_crc  = update_status.app_crc;
        settings.bank_0_size = update_status.app_size;
        settings.bank_0      = BANK_VALID_APP;
        settings.bank_1      = BANK_INVALID_APP;
        
        m_update_status      = BOOTLOADER_SETTINGS_SAVING;
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_TIMEOUT)
    {
        // Timeout has occurred. Close the connection with the DFU Controller.
        uint32_t err_code = dfu_transport_close();
        APP_ERROR_CHECK(err_code);

        m_update_status      = BOOTLOADER_TIMEOUT;
    }
    else if (update_status.status_code == DFU_BANK_0_ERASED)
    {
        settings.bank_0_crc  = 0;
        settings.bank_0_size = 0;
        settings.bank_0      = BANK_ERASED;
        settings.bank_1      = p_bootloader_settings->bank_1;
        
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_BANK_1_ERASED)
    {
        settings.bank_0      = p_bootloader_settings->bank_0;
        settings.bank_0_crc  = p_bootloader_settings->bank_0_crc;
        settings.bank_0_size = p_bootloader_settings->bank_0_size;
        settings.bank_1      = BANK_ERASED;
        
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_RESET)
    {
        // Timeout has occurred. Close the connection with the DFU Controller.
        uint32_t err_code = dfu_transport_close();
        APP_ERROR_CHECK(err_code);

        m_update_status      = BOOTLOADER_RESET;
    }
    else
    {
        // No implementation needed.
    }
}
Exemplo n.º 9
0
void bootloader_settings_get(bootloader_settings_t * const p_settings)
{
    const bootloader_settings_t * p_bootloader_settings;
    bootloader_util_settings_get(&p_bootloader_settings);

    p_settings->bank_0      = p_bootloader_settings->bank_0;
    p_settings->bank_0_crc  = p_bootloader_settings->bank_0_crc;
    p_settings->bank_0_size = p_bootloader_settings->bank_0_size;
    p_settings->bank_1      = p_bootloader_settings->bank_1;
}
bool bootloader_dfu_sd_in_progress(void)
{
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    if (p_bootloader_settings->bank_0 == BANK_VALID_SD ||
            p_bootloader_settings->bank_1 == BANK_VALID_BOOT)
    {
        return true;
    }

    return false;
}
Exemplo n.º 11
0
void bootloader_settings_get(bootloader_settings_t * const p_settings)
{
    const bootloader_settings_t *  p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    p_settings->bank_0         = p_bootloader_settings->bank_0;
    p_settings->bank_0_crc     = p_bootloader_settings->bank_0_crc;
    p_settings->bank_0_size    = p_bootloader_settings->bank_0_size;
    p_settings->bank_1         = p_bootloader_settings->bank_1;
    p_settings->sd_image_size  = p_bootloader_settings->sd_image_size;
    p_settings->bl_image_size  = p_bootloader_settings->bl_image_size;
    p_settings->app_image_size = p_bootloader_settings->app_image_size;
    p_settings->sd_image_start = p_bootloader_settings->sd_image_start;
}
Exemplo n.º 12
0
uint32_t dfu_bl_image_swap(void)
{
    const bootloader_settings_t * p_bootloader_settings;
    sd_mbr_command_t sd_mbr_cmd;

    bootloader_util_settings_get(&p_bootloader_settings);

    if (p_bootloader_settings->bl_image.st.size != 0)
    {
        sd_mbr_cmd.command               = SD_MBR_COMMAND_COPY_BL;
        sd_mbr_cmd.params.copy_bl.bl_src = (uint32_t *)(p_bootloader_settings->src_image_address + p_bootloader_settings->sd_image.st.size);
        sd_mbr_cmd.params.copy_bl.bl_len = p_bootloader_settings->bl_image.st.size / sizeof(uint32_t);

        return sd_mbr_command(&sd_mbr_cmd);
    }
    return NRF_SUCCESS;
}
Exemplo n.º 13
0
bool bootloader_app_is_valid(uint32_t app_addr)
{
    // There exists an application in CODE region 1.
    if (DFU_BANK_0_REGION_START == EMPTY_FLASH_MASK)
    {
        return false;
    }

#if 0
    const bootloader_settings_t * p_bootloader_settings;
    bool success = false;

    switch (app_addr)
    {
        case DFU_BANK_0_REGION_START:
            bootloader_util_settings_get(&p_bootloader_settings);

            // The application in CODE region 1 is flagged as valid during update.
            if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
            {
                uint16_t image_crc = 0;

                // A stored crc value of 0 indicates that CRC checking is not used.
                if (p_bootloader_settings->bank_0_crc != 0)
                {
                    image_crc = crc16_compute((uint8_t*)DFU_BANK_0_REGION_START,
                                              p_bootloader_settings->bank_0_size,
                                              NULL);
                }

                success = (image_crc == p_bootloader_settings->bank_0_crc);
            }
            break;

        case DFU_BANK_1_REGION_START:
        default:
            // No implementation needed.
            break;
    }

    return success;
#else
    return true;
#endif
}
Exemplo n.º 14
0
uint32_t dfu_sd_image_swap(void)
{
    const bootloader_settings_t *   p_bootloader_settings;
    sd_mbr_command_t                sd_mbr_cmd;

    bootloader_util_settings_get(&p_bootloader_settings);

    if (p_bootloader_settings->sd_image.st.size != 0)
    {
        sd_mbr_cmd.command            = SD_MBR_COMMAND_COPY_SD;
        sd_mbr_cmd.params.copy_sd.src = (uint32_t *) p_bootloader_settings->src_image_address;
        sd_mbr_cmd.params.copy_sd.dst = (uint32_t *) SOFTDEVICE_REGION_START;
        sd_mbr_cmd.params.copy_sd.len = p_bootloader_settings->sd_image.st.size / sizeof(uint32_t);

        return sd_mbr_command(&sd_mbr_cmd);
    }
    return NRF_SUCCESS;
}
Exemplo n.º 15
0
uint32_t dfu_sd_image_validate(void)
{
    const bootloader_settings_t * p_bootloader_settings;
    sd_mbr_command_t      sd_mbr_cmd;

    bootloader_util_settings_get(&p_bootloader_settings);

    if (p_bootloader_settings->sd_image.st.size != 0)
    {
        sd_mbr_cmd.command             = SD_MBR_COMMAND_COMPARE;
        sd_mbr_cmd.params.compare.ptr1 = (uint32_t *) SOFTDEVICE_REGION_START;
        sd_mbr_cmd.params.compare.ptr2 = (uint32_t *) p_bootloader_settings->src_image_address;
        sd_mbr_cmd.params.compare.len  = p_bootloader_settings->sd_image.st.size / sizeof(uint32_t);

        return sd_mbr_command(&sd_mbr_cmd);
    }
    return NRF_SUCCESS;
}
Exemplo n.º 16
0
static void bootloader_settings_save(bootloader_settings_t settings)
{
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    // Save needed data for later use. 
    uint32_t settings_page = ((uint32_t) p_bootloader_settings) / NRF_FICR->CODEPAGESIZE;

    uint32_t num_of_words = sizeof(bootloader_settings_t) / sizeof(uint32_t);

    // Save bootloader settings.
    uint32_t err_code = ble_flash_page_erase(settings_page);
    APP_ERROR_CHECK(err_code);    
    err_code          = ble_flash_block_write((uint32_t *)p_bootloader_settings, 
                                              (uint32_t *)&settings, 
                                              num_of_words);
    APP_ERROR_CHECK(err_code);
}
Exemplo n.º 17
0
bool bootloader_dfu_sd_in_progress(void)
{
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);
#if DEBUG_BOOTLOADER_EN
  //simple_uart_init();
  DbgPrintf_str("check bootloader_dfu_sd_in_progress,p_bootloader_settings->bank_0,bank_1:\r\n");
  DbgPrintf_hex(p_bootloader_settings->bank_0);
  DbgPrintf_hex(p_bootloader_settings->bank_1);
#endif
    if (p_bootloader_settings->bank_0 == BANK_VALID_SD ||
        p_bootloader_settings->bank_1 == BANK_VALID_BOOT)
    {
        return true;
    }

    return false;
}
Exemplo n.º 18
0
bool bootloader_app_is_valid(uint32_t app_addr)
{
    const bootloader_settings_t * p_bootloader_settings;

    // There exists an application in CODE region 1.
    if (*((uint32_t *)app_addr) == EMPTY_FLASH_MASK)
    {
        return false;
    }

    bool success = false;

    bootloader_util_settings_get(&p_bootloader_settings);
#if DEBUG_BOOTLOADER_EN
  //simple_uart_init();
  DbgPrintf_str("\r\ncheck bootloader_app_is_valid,bank_0:"); 
  DbgPrintf_hex(p_bootloader_settings->bank_0);
  DbgPrintf_str("crc:"); 
  DbgPrintf_hex(p_bootloader_settings->bank_0_crc);
  DbgPrintf_str("size:"); 
  DbgPrintf_hex(p_bootloader_settings->bank_0_size);
#endif
    // The application in CODE region 1 is flagged as valid during update.
    if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
    {
        uint16_t image_crc = 0;

        // A stored crc value of 0 indicates that CRC checking is not used.
        if (p_bootloader_settings->bank_0_crc != 0)
        {
            image_crc = crc16_compute((uint8_t *)DFU_BANK_0_REGION_START,
                                      p_bootloader_settings->bank_0_size,
                                      NULL);
        }

        success = (image_crc == p_bootloader_settings->bank_0_crc);
    }

    return success;
}
void bootloader_dfu_update_process(dfu_update_status_t update_status)
{
    static bootloader_settings_t  settings;
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    if (update_status.status_code == DFU_UPDATE_APP_COMPLETE)
    {
        settings.bank_0_crc  = update_status.app_crc;
        settings.bank_0_size = update_status.app_size;
        settings.bank_0      = BANK_VALID_APP;
        settings.bank_1      = BANK_INVALID_APP;

        m_update_status      = BOOTLOADER_SETTINGS_SAVING;
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE)
    {
        settings.bank_0_crc     = update_status.app_crc;
        settings.bank_0_size    = update_status.sd_size +
                                  update_status.bl_size +
                                  update_status.app_size;
        settings.bank_0         = BANK_VALID_SD;
        settings.bank_1         = BANK_INVALID_APP;
        settings.sd_image_size  = update_status.sd_size;
        settings.bl_image_size  = update_status.bl_size;
        settings.app_image_size = update_status.app_size;
        settings.sd_image_start = update_status.sd_image_start;

        m_update_status         = BOOTLOADER_SETTINGS_SAVING;
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_UPDATE_BOOT_COMPLETE)
    {
        settings.bank_0         = p_bootloader_settings->bank_0;
        settings.bank_0_crc     = p_bootloader_settings->bank_0_crc;
        settings.bank_0_size    = p_bootloader_settings->bank_0_size;
        settings.bank_1         = BANK_VALID_BOOT;
        settings.sd_image_size  = update_status.sd_size;
        settings.bl_image_size  = update_status.bl_size;
        settings.app_image_size = update_status.app_size;
        settings.bl_image_start = CODE_REGION_1_START;

        m_update_status         = BOOTLOADER_SETTINGS_SAVING;
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_UPDATE_SD_SWAPPED)
    {
        if (p_bootloader_settings->bank_0 == BANK_VALID_SD)
        {
            settings.bank_0_crc     = 0;
            settings.bank_0_size    = 0;
            settings.bank_0         = BANK_INVALID_APP;
        }
        // This handles cases where SoftDevice was not updated, hence bank0 keeps its settings.
        else
        {
            settings.bank_0         = p_bootloader_settings->bank_0;
            settings.bank_0_crc     = p_bootloader_settings->bank_0_crc;
            settings.bank_0_size    = p_bootloader_settings->bank_0_size;
        }

        settings.bank_1         = BANK_INVALID_APP;
        settings.sd_image_size  = 0;
        settings.bl_image_size  = 0;
        settings.app_image_size = 0;

        m_update_status         = BOOTLOADER_SETTINGS_SAVING;
        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_TIMEOUT)
    {
        // Timeout has occurred. Close the connection with the DFU Controller.
        uint32_t err_code = dfu_transport_close();
        APP_ERROR_CHECK(err_code);

        m_update_status = BOOTLOADER_TIMEOUT;
    }
    else if (update_status.status_code == DFU_BANK_0_ERASED)
    {
        settings.bank_0_crc  = 0;
        settings.bank_0_size = 0;
        settings.bank_0      = BANK_INVALID_APP;
        settings.bank_1      = p_bootloader_settings->bank_1;

        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_RESET)
    {
        m_update_status = BOOTLOADER_RESET;
    }
    else
    {
        // No implementation needed.
    }
}
Exemplo n.º 20
0
void bootloader_dfu_update_process(dfu_update_status_t update_status)
{
    static bootloader_settings_t    settings;
    const bootloader_settings_t *   p_bootloader_settings;
    uint32_t                        err_code;

    bootloader_util_settings_get(&p_bootloader_settings);                                   /* Extract current values of the bootloader_settings*/
    memcpy(&settings, p_bootloader_settings, sizeof(bootloader_settings_t));                /* Copy over to local bootloader_settings*/

    if (update_status.status_code == DFU_UPDATE_NEW_IMAGES)
    {
        if (update_status.sd_image_size != NEW_IMAGE_SIZE_EMPTY)
        {
            settings.sd_image.st.size = update_status.sd_image_size;
            settings.sd_image.st.bank = update_status.bank_used;
        }
        else
        {
            settings.sd_image.st.size = NEW_IMAGE_SIZE_EMPTY;
        }

        if (update_status.bl_image_size != NEW_IMAGE_SIZE_EMPTY)
        {
            settings.bl_image.st.size = update_status.bl_image_size;
            settings.bl_image.st.bank = update_status.bank_used;
        }
        else
        {
            settings.bl_image.st.size = NEW_IMAGE_SIZE_EMPTY;
        }

        if (update_status.ap_image_size != NEW_IMAGE_SIZE_EMPTY)
        {
            settings.ap_image.st.size = update_status.ap_image_size;
            settings.ap_image.st.bank = update_status.bank_used;
        }
        else
        {
            settings.ap_image.st.size = NEW_IMAGE_SIZE_EMPTY;
        }

        settings.src_image_address = update_status.src_image_address;
        m_update_status             = BOOTLOADER_SETTINGS_SAVING;

        /*Clears bootloader_settings critical flag - in case it was used by MBR*/
        if (*((uint32_t *)BOOT_SETTINGS_PEND_ADDRESS) != 0xFFFFFFFF)
        {
            err_code = blocking_flash_page_erase(BOOT_SETTINGS_PEND_ADDRESS/CODE_PAGE_SIZE);
            APP_ERROR_CHECK(err_code);
        }

        // TEMPORARY: This serves as a critical flag for the bootloader_settings updating.
        err_code = blocking_flash_word_write((uint32_t *)BOOT_SETTINGS_PEND_ADDRESS,
                                             BOOT_SETTINGS_PEND_VALUE);
        APP_ERROR_CHECK(err_code);

        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_UPDATE_AP_SWAPPED)
    {
        settings.ap_image.st.bank   = NEW_IMAGE_BANK_DONE;
        settings.ap_image.st.size   = p_bootloader_settings->ap_image.st.size;
        settings.valid_app          = BOOTLOADER_SETTINGS_VALID_APPLICATION;
        m_update_status             = BOOTLOADER_SETTINGS_SAVING;

        /*Clears bootloader_settings critical flag - in case it was used by MBR*/
        if (*((uint32_t *)BOOT_SETTINGS_PEND_ADDRESS) != 0xFFFFFFFF)
        {
            err_code = blocking_flash_page_erase(BOOT_SETTINGS_PEND_ADDRESS/CODE_PAGE_SIZE);
            APP_ERROR_CHECK(err_code);
        }

        // TEMPORARY: This serves as a critical flag for the bootloader_settings updating.
        err_code = blocking_flash_word_write((uint32_t *)BOOT_SETTINGS_PEND_ADDRESS,
                                             BOOT_SETTINGS_PEND_VALUE);
        APP_ERROR_CHECK(err_code);

        bootloader_settings_save(&settings);
    }
    else if (update_status.status_code == DFU_UPDATE_AP_INVALIDATED)
    {
        if (p_bootloader_settings->valid_app != BOOTLOADER_SETTINGS_INVALID_APPLICATION)
        {
            settings.valid_app          = BOOTLOADER_SETTINGS_INVALID_APPLICATION;
            m_update_status             = BOOTLOADER_UPDATING;
            bootloader_settings_save(&settings);
        }
    }
    else if (update_status.status_code == DFU_TIMEOUT)
    {
        // Timeout has occurred. Close the connection with the DFU Controller.
//        dfu_transport_close();

        m_update_status      = BOOTLOADER_TIMEOUT;
    }
    else if (update_status.status_code == DFU_RESET)
    {
        // Timeout has occurred. Close the connection with the DFU Controller.
//        dfu_transport_close();

        m_update_status      = BOOTLOADER_RESET;
    }
    else
    {
        // No implementation needed.
    }
}