Esempio n. 1
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;
}
Esempio n. 2
0
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t  err_code;
    uint32_t  data_length;
    uint8_t * p_data;
    
    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Check pointer alignment.
    if (!is_word_aligned(p_packet->p_data_packet))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

    switch (m_dfu_state)
    {
        case DFU_STATE_RDY:
            // Fall-through.
        
        case DFU_STATE_RX_INIT_PKT:
            m_dfu_state = DFU_STATE_RX_DATA_PKT;
        
            // Fall-through.
        
        case DFU_STATE_RX_DATA_PKT:
            data_length = p_packet->packet_length  * sizeof(uint32_t);
            if ((uint32_t)(m_received_data + data_length) > m_image_size)
            {
                // The caller is trying to write more bytes into the flash than the size provided to 
                // the dfu_image_size_set function.
                return NRF_ERROR_DATA_SIZE;
            }

            p_data   = (uint8_t *)p_packet->p_data_packet;            
            err_code = pstorage_raw_store(&m_storage_handle_app, p_data, data_length, m_received_data);
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
            m_received_data += data_length;        
            
            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;    
}
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t   data_length;
    uint32_t   err_code;
    uint32_t * p_data;

    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Check pointer alignment.
    if(((uint32_t) (p_packet->p_data_packet)) & (sizeof(uint32_t) - 1))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

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

        case DFU_STATE_RX_DATA_PKT:
            data_length = p_packet->packet_length * sizeof(uint32_t);

            if ((m_app_data_received + data_length) > m_image_size)
            {
                // The caller is trying to write more bytes into the flash than the size provided to 
                // the dfu_image_size_set function. This is treated as a serious error condition and 
                // an unrecoverable one. Hence point the variable mp_app_write_address to the top of 
                // the flash area. This will ensure that all future application data packet writes 
                // will be blocked because of the above check.
                m_app_data_received = 0xFFFFFFFF;;

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

            p_data = (uint32_t *)p_packet->p_data_packet;

            err_code = pstorage_raw_store(&m_storage_handle_swap, (uint8_t*) p_data, data_length, m_app_data_received);
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
            
            m_app_data_received += data_length;

            if (m_app_data_received != m_image_size)
            {
                // The entire image is not received yet. More data is expected.
                err_code = NRF_ERROR_INVALID_LENGTH;
            }
            else
            {
                // The entire image has been received. Return NRF_SUCCESS.
                err_code = NRF_SUCCESS;
            }
            break;

        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;            
    }     

    return err_code;    
}
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t  err_code;
    uint32_t  data_length;
    uint8_t * p_data;

    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Check pointer alignment.
    if (!is_word_aligned(p_packet->p_data_packet))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

    switch (m_dfu_state)
    {
    case DFU_STATE_RDY:
    // Fall-through.

    case DFU_STATE_RX_INIT_PKT:
        m_dfu_state = DFU_STATE_RX_DATA_PKT;

    // Fall-through.

    case DFU_STATE_RX_DATA_PKT:
        data_length = p_packet->packet_length  * sizeof(uint32_t);
        if ((uint32_t)(m_received_data + data_length) > m_image_size)
        {
            // The caller is trying to write more bytes into the flash than the size provided to
            // the dfu_image_size_set function.
            return NRF_ERROR_DATA_SIZE;
        }

        p_data   = (uint8_t *)p_packet->p_data_packet;
        err_code = pstorage_raw_store(&m_storage_handle_app, p_data, data_length, m_received_data);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        m_received_data += data_length;

        // SINGLEBANK PATCH: added so that it will return NRF_ERROR_INVALID_LENGTH instead of NRF_SUCCESS if the full image is not received.
        if (m_received_data != m_image_size)
        {
            // The entire image is not received yet. More data is expected.

            err_code = NRF_ERROR_INVALID_LENGTH;
        }
        else
        {
            // The entire image has been received. Return NRF_SUCCESS.

            err_code = NRF_SUCCESS;
        }
        //PATCH END
        break;

    default:
        err_code = NRF_ERROR_INVALID_STATE;
        break;
    }

    return err_code;
}