コード例 #1
0
ファイル: dfu_dual_bank.c プロジェクト: IOIOI/nRF51
uint32_t dfu_image_validate(uint16_t crc_seed)
{
    uint32_t err_code;

    switch (m_dfu_state)
    {
        case DFU_STATE_RX_DATA_PKT:
            m_dfu_state = DFU_STATE_VALIDATE;

            // Check if the application image write has finished.
            if (m_data_received != m_image_size)
            {
                // Image not yet fully transfered by the peer or the peer has attempted to write
                // too much data. Hence the validation should fail.
                err_code = NRF_ERROR_INVALID_STATE;
            }
            else
            {
                // Valid peer activity detected. Hence restart the DFU timer.
                err_code = dfu_timer_restart();
                if (err_code == NRF_SUCCESS)
                {
                    if(crc_crc16_update(crc_seed, (uint32_t*)dfu_storage_start_address_get(), m_image_size) == 0)
                    {
                        m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE;
                        err_code = NRF_SUCCESS;
                    }
                    else
                    {
                        err_code = NRF_ERROR_INTERNAL;
                    }
                }
            }
            break;

        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }

    return err_code;
}
コード例 #2
0
ファイル: dfu_transport_ant.c プロジェクト: IOIOI/nRF51
/**@brief Function for processing ANTFS upload data event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_upload_data_handle(const antfs_event_return_t * p_event)
{
    static uint8_t *        p_rxd_data;
    static uint32_t         rxd_data_size;
    uint32_t                err_code = NRF_SUCCESS;
    ota_image_header_t *    p_ota_image_header;

     // Allocate a memory pool for upload buffering.
    if (m_data_buffered == 0)
    {
        // Check which pool is empty.
        if (m_mem_pool_1.size == 0)
        {
            mp_buffering_handle = &m_mem_pool_1;
        }
        else if (m_mem_pool_2.size == 0)
        {
            mp_buffering_handle = &m_mem_pool_2;
        }
        else
        {
            // something is wrong.
            dfu_error_notify(err_code, 6);
        }
        mp_rx_buffer = &mp_buffering_handle->a_mem_pool[0];
    }

    if ((p_event->bytes + m_data_buffered) < ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)
    {
        // Copy over the buffer the rx'd 8 byte data
        memcpy(mp_rx_buffer + m_data_buffered, p_event->data, p_event->bytes);
        // Advance buffered count
        m_data_buffered += p_event->bytes;
        // Advance current over all data count.
    }
    else
    {
        // something is wrong.
        dfu_error_notify(err_code, 7);
    }

    if ((m_data_buffered >= ANTFS_UPLOAD_DATA_BUFFER_MIN_SIZE) ||
            ((m_pending_offset + m_data_buffered) >= m_current_file_size))
    {
        /* If any of the pool is still pending process and we are running out of space
        * The ANTFS_UPLOAD_DATA_BUFFER_MIN_SIZE should be enough delay to get the previous buffer be processed, including flashing*/
        if (((m_mem_pool_1.size != 0) || (m_mem_pool_2.size != 0)) && ((m_pending_offset + m_data_buffered) < m_current_file_size))
        {
            if (m_data_buffered < ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)
            {   // We can wait for a bit.
                return;
            }
            else
            {
                // Something is wrong. the device is not flashing.
                upload_data_response_fail_reset();
                return;
            }
        }

        mp_buffering_handle->size   = m_data_buffered;          // Set the size and consider this pool closed and ready for processing.
        m_data_buffered             = 0;                        // Reset buffered data count

        // Decide what to do with the data in the buffer.
        switch (m_current_file_index)
        {
            case ANTFS_FILE_INDEX_UPDATE_STACK:
            case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER:
            case ANTFS_FILE_INDEX_UPDATE_APPLICATION:
            case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER:

                // Not in the right state
                if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY)
                {
                    // Throw it away.
                    mp_buffering_handle->size   = 0;
                    mp_buffering_handle         = NULL;

                    upload_data_response_fail_reset();
                    return;
                }

                p_rxd_data      = mp_buffering_handle->a_mem_pool;
                rxd_data_size   = mp_buffering_handle->size;

                // pre calculate pending offset
                m_pending_offset  = m_pending_offset + rxd_data_size;

                /***********
                 * Header Section
                 */
                if (!m_ota_image_header_parsed)
                {
                    // Parse the Header
                    if (antfs_ota_image_header_parsing(&p_rxd_data, &rxd_data_size))
                    {
                        m_ota_image_header_parsed = true;
                        p_ota_image_header = antfs_ota_image_header_get();
                    }
                    else
                    {
                        return;                                         // Get more
                    }

                    if ((p_ota_image_header == NULL)                                                        ||  // Make sure it is a valid header
                        (p_ota_image_header->architecture_identifier != OTA_IMAGE_ARCH_IDENTIFIER_ST_BL_AP) ||  // Make sure it is SD BL and AP arch
                        (p_ota_image_header->image_format != OTA_IMAGE_IMAGE_FORMAT_BINARY))                    // Make sure it is in Binary format
                    {
                        // Invalid header, fail now.
                        upload_data_response_fail_reset();
                        return;
                    }

                    // Fill in DFU parameters
                    m_dfu_pkt.params.start_packet.dfu_update_mode   = m_update_mode;
                    m_dfu_pkt.params.start_packet.sd_image_size     = p_ota_image_header->wireless_stack_size;
                    m_dfu_pkt.params.start_packet.bl_image_size     = p_ota_image_header->bootloader_size;
                    m_dfu_pkt.params.start_packet.app_image_size    = p_ota_image_header->application_size;
                    m_dfu_pkt.params.start_packet.info_bytes_size   = OTA_IMAGE_CRC_SIZE_MAX;

                    err_code = dfu_start_pkt_handle(&m_dfu_pkt);        // reinitializing dfu pkt
                    if (err_code)
                    {
                        upload_data_response_fail_reset();
                        return;
                    }

                    m_image_data_max    = p_ota_image_header->wireless_stack_size   +
                                          p_ota_image_header->bootloader_size       +
                                          p_ota_image_header->application_size      +
                                          OTA_IMAGE_CRC_SIZE_MAX;
                    m_header_crc_seed   = antfs_ota_image_header_crc_get();
                    m_current_crc       = m_header_crc_seed;
                    m_current_offset    = p_ota_image_header->header_size;
                }

                /***********
                 * Image Section
                 */
                if (!m_image_data_complete)
                {
                    m_upload_swap_space_prepared = false;

                    m_dfu_pkt.params.data_packet.p_data_packet  = (uint32_t*) p_rxd_data;
                    m_dfu_pkt.params.data_packet.packet_length  = rxd_data_size / sizeof(uint32_t);

                    // store flushed information for flash write verification.
                    mp_buffering_handle->size                   = rxd_data_size;
                    mp_buffering_handle->crc                    = crc_crc16_update(0, p_rxd_data, rxd_data_size);

                    // Pass the image to dfu.
                    m_dfu_pkt.packet_type        = DATA_PACKET;
                    err_code = dfu_data_pkt_handle(&m_dfu_pkt);
                    if (err_code == NRF_SUCCESS)
                    {
                        // All the expected firmware image has been received and processed successfully.
                        m_image_data_complete = true;
                    }
                    else if (err_code == NRF_ERROR_INVALID_LENGTH)
                    {
                        // The image is still partially completed. We need more.
                        //do nothing;
                    }
                    // Unmanaged return code. Something is wrong need to abort.
                    else
                    {
                        //TODO Need to figure out what to do on unmanaged returns. Maybe reset
                        dfu_error_notify(err_code, 9);
                    }
                }

                m_antfs_dfu_state = ANTFS_DFU_STATE_READY;

                break;

            default:
                mp_buffering_handle->size = 0;
                break;
        }
    }
}
コード例 #3
0
ファイル: dfu_transport_ant.c プロジェクト: IOIOI/nRF51
/*
 * NOTE: This callback is only called by the following
 *  - Storing done operation by dfu_data_pkt_handle
 *  - And all clearing done operation.
 */
static void dfu_cb_handler(uint32_t result, uint8_t * p_data)
{
    uint32_t err_code;
    uint16_t rxd_buffer_len = 0;
    uint16_t ram_crc        = 0;
    uint16_t flash_crc      = 0;

#if defined (DBG_DFU_UART_OUT_PIN)
    DEBUG_UART_OUT(0xFF);
    DEBUG_UART_OUT(m_antfs_dfu_state);
#endif

    switch (m_antfs_dfu_state)
    {
        case ANTFS_DFU_STATE_INIT_DELAYED:
            // This is when upon initialization, a pre-erase operation have occured i.e. bank1 pre clearing.
            services_init();
            break;

        case ANTFS_DFU_STATE_FLASH_ERASE:
            // Handles upload and download request response delay when there is ongoing flash activities
            // Generally we need to avoid flash activities and burst activities to happen at the same time.
            // ANTFS request response are delayed and when flash is done response are handled here.
            if (m_upload_request_in_progress)
            {
                m_upload_request_in_progress    = false;
                // Make sure we got all the latest values.
                m_response_info.file_size.data  = m_current_offset;
                m_response_info.file_crc        = m_current_crc;
                if (result == NRF_SUCCESS)
                {
                    m_upload_swap_space_prepared = true;
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
                }
                else
                {
                    /* Not ready */
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_UPLOAD_NOT_READY, &m_response_info));
                }
            }

            if (m_download_request_in_progress)
            {
                m_download_request_in_progress = false;

                UNUSED_VARIABLE(antfs_download_req_resp_prepare(RESPONSE_MESSAGE_OK, &m_response_info));
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            break;


        case ANTFS_DFU_STATE_FLASH_PENDING:
        case ANTFS_DFU_STATE_READY:
            // Handles Flash write call back queued by Upload Data.
            if (result != NRF_SUCCESS)
            {
                upload_data_response_fail_reset();
                return;
            }

            if ((m_mem_pool_1.a_mem_pool <= p_data) && (p_data <= (m_mem_pool_1.a_mem_pool + ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)))
            {
                rxd_buffer_len = m_mem_pool_1.size;
                ram_crc = m_mem_pool_1.crc;
                m_mem_pool_1.size = 0;
            }
            else if ((m_mem_pool_2.a_mem_pool <= p_data) && (p_data <= (m_mem_pool_2.a_mem_pool + ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)))
            {
                rxd_buffer_len = m_mem_pool_2.size;
                ram_crc = m_mem_pool_2.crc;
                m_mem_pool_2.size = 0;
            }
            else
            {
                upload_data_response_fail_reset();
                return;
            }

            // Verify the data written to flash.
            flash_crc = crc_crc16_update(0, (uint8_t*)(dfu_storage_start_address_get() + m_image_data_offset), rxd_buffer_len);
            if (flash_crc != ram_crc)
            {
                upload_data_response_fail_reset();
                return;
            }

            //update current offsets and crc
            m_current_offset    += rxd_buffer_len;
            m_current_crc       = crc_crc16_update(m_current_crc, (uint8_t*)(dfu_storage_start_address_get() + m_image_data_offset), rxd_buffer_len);

            m_image_data_offset += rxd_buffer_len;

            if (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING)
            {
                m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
                // Update it with the latest values;
                m_response_info.file_size.data            = m_current_offset;
                m_response_info.file_crc                  = m_current_crc;
                if (m_upload_request_in_progress)
                {
                    m_upload_request_in_progress = false;
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
                }
                else    // data response
                {
                    if (m_image_data_complete == true)
                    {
                        if (m_image_data_max == m_image_data_offset)
                        {
                            err_code = dfu_image_validate(m_header_crc_seed);
                            if (err_code == NRF_SUCCESS)
                            {
                                UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
                                m_antfs_dfu_state = ANTFS_DFU_STATE_VALIDATED;
                                return;
                            }
                            else
                            {
                                upload_data_response_fail_reset();
                            }
                        }

                        if ((m_mem_pool_1.size != 0) || (m_mem_pool_2.size != 0))
                        {
                            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                        }
                    }
                    else //m_image_data_complete == false
                    {
                        if ((m_mem_pool_1.size == 0) && (m_mem_pool_2.size == 0))
                        {
                            UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));                 // Handles block transfers
                        }
                        else
                        {
                            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                        }
                    }
                }
            }

            break;

        default:
            break;
    }
}
コード例 #4
0
ファイル: antfs_ota.c プロジェクト: dhruvkakadiya/OpenSJ_Bluz
uint16_t antfs_ota_image_header_crc_get (void)
{
    return  crc_crc16_update(HEADER_CRC_SEED, m_ota_image_header, m_ota_image_header_count);
}