Ejemplo n.º 1
0
uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t err_code;
    uint32_t total_image_size = p_packet->params.init_packet.total_image_size;
    dfu_update_status_t update_status;

    switch (m_dfu_state)
    {
        case DFU_STATE_IDLE:
        case DFU_STATE_RDY:
        case DFU_STATE_RX_DATA_PKT:
            m_dfu_state = DFU_STATE_RX_INIT_PKT;
            /* fall-through */

        case DFU_STATE_RX_INIT_PKT:
            // Valid peer activity detected. Hence restart the DFU timer.
            err_code = dfu_timer_restart();
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }

            // Reset the number of data received and the original m_storage_handle_app's start address.
            m_data_received = 0;
            m_storage_handle_app.block_id   = CODE_REGION_1_START;

            // Prepare the flash buffer for the upcoming image.
            if (total_image_size > DFU_IMAGE_MAX_SIZE_BANKED)
            {
                update_status.status_code = DFU_UPDATE_AP_INVALIDATED;
                bootloader_dfu_update_process(update_status);
                err_code = pstorage_raw_clear(&m_storage_handle_app, DFU_IMAGE_MAX_SIZE_FULL);
                m_active_bank = NEW_IMAGE_BANK_0;
            }
            else if ((total_image_size < DFU_IMAGE_MAX_SIZE_BANKED) && (total_image_size != 0))
            {
                err_code = pstorage_raw_clear(&m_storage_handle_swap, DFU_IMAGE_MAX_SIZE_BANKED);
                m_active_bank = NEW_IMAGE_BANK_1;
            }
            else
            {
                // do nothing
            }

            break;

        default:
            // Either the start packet was not received or dfu_init function was not called before.
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }

    return err_code;
}
Ejemplo n.º 2
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;
}
uint32_t dfu_init(void)
{
    uint32_t              err_code;
    bootloader_settings_t bootloader_settings;
    dfu_update_status_t   update_status;
    
    m_storage_module_param.cb          = pstorage_callback_handler;
    
    // Clear swap area.
    uint32_t * p_bank_start_address = (uint32_t *)DFU_BANK_1_REGION_START; 
    
    m_init_packet_length  = 0;
    m_image_crc           = 0;    
           
    err_code = pstorage_raw_register(&m_storage_module_param, &m_storage_handle_app);
    if (err_code != NRF_SUCCESS)
    {
        m_dfu_state = DFU_STATE_INIT_ERROR;
        return err_code;
    }
    
    m_storage_handle_app.block_id   = CODE_REGION_1_START;
    m_storage_handle_swap           = m_storage_handle_app;
    m_storage_handle_swap.block_id += DFU_IMAGE_MAX_SIZE_BANKED;
    
    bootloader_settings_get(&bootloader_settings);
    if ((bootloader_settings.bank_1 != BANK_ERASED) || (*p_bank_start_address != EMPTY_FLASH_MASK))
    {
        err_code = pstorage_raw_clear(&m_storage_handle_swap, DFU_IMAGE_MAX_SIZE_BANKED);
        if (err_code != NRF_SUCCESS)
        {
            m_dfu_state = DFU_STATE_INIT_ERROR;
            return err_code;
        }
        
        update_status.status_code = DFU_BANK_1_ERASED;
        bootloader_dfu_update_process(update_status);
    }
    
    // Create the timer to monitor the activity by the peer doing the firmware update.
    err_code = app_timer_create(&m_dfu_timer_id,
                                APP_TIMER_MODE_SINGLE_SHOT,
                                dfu_timeout_handler);
    APP_ERROR_CHECK(err_code);

    // Start the DFU timer.
    err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);

    // Size which indicates how large application DFU are able to handle.
    // The area is not erased but has been locked by the running application, and is considered
    // to be application data save space.
    m_new_app_max_size = DFU_IMAGE_MAX_SIZE_BANKED;
    
    m_app_data_received = 0;
    m_dfu_state         = DFU_STATE_IDLE;        

    return NRF_SUCCESS;
}
uint32_t dfu_image_size_set(uint32_t image_size)
{
    uint32_t            err_code;
    dfu_update_status_t update_status;

    err_code = NRF_ERROR_INVALID_STATE;

    if (image_size > DFU_IMAGE_MAX_SIZE_FULL)
    {
        return NRF_ERROR_DATA_SIZE;
    }

    if ((image_size & (sizeof(uint32_t) - 1)) != 0)
    {
        // Image_size is not a multiple of 4 (word size).
        return NRF_ERROR_NOT_SUPPORTED;
    }

    switch (m_dfu_state)
    {
    case DFU_STATE_IDLE:
        err_code = pstorage_raw_clear(&m_storage_handle_app, image_size);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }

        m_received_data           = 0;
        m_image_size              = image_size;


        update_status.status_code = DFU_BANK_0_ERASED;
        //SINGLEBANK PATCH
        err_code = 0;
        //m_dfu_state               = DFU_STATE_RDY;
        //END PATCH
        bootloader_dfu_update_process(update_status);
        break;

    default:
        err_code = NRF_ERROR_INVALID_STATE;
        break;
    }

    return err_code;
}
uint32_t dfu_image_activate()
{
    uint32_t            err_code;
    
    switch (m_dfu_state)
    {    
        case DFU_STATE_WAIT_4_ACTIVATE:
            
            // Stop the DFU Timer because the peer activity need not be monitored any longer.
            err_code = app_timer_stop(m_dfu_timer_id);
            APP_ERROR_CHECK(err_code);
            
            // Erase BANK 0.
            err_code = pstorage_raw_clear(&m_storage_handle_app, m_image_size);
            APP_ERROR_CHECK(err_code);

            err_code = pstorage_raw_store(&m_storage_handle_app, (uint8_t*) m_storage_handle_swap.block_id, m_image_size, 0);

            if (err_code == NRF_SUCCESS)
            {
                dfu_update_status_t update_status;

                update_status.status_code = DFU_UPDATE_COMPLETE;
                update_status.app_crc     = m_image_crc;                
                update_status.app_size    = m_image_size;

                bootloader_dfu_update_process(update_status);        
            }
            break;
            
        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }
    
    return err_code;    
}