Exemple #1
0
/**@brief Function for activating received Application image.
 *
 *  @details This function will move the received application image fram swap (bank 1) to
 *           application area (bank 0).
 *
 * @return NRF_SUCCESS on success. Error code otherwise.
 */
static uint32_t dfu_activate_app(void)
{
    uint32_t err_code;

    // Erase BANK 0.
    err_code = pstorage_clear(&m_storage_handle_app, m_start_packet.app_image_size);
    APP_ERROR_CHECK(err_code);

    err_code = pstorage_store(&m_storage_handle_app,
                                  (uint8_t *)m_storage_handle_swap.block_id,
                                  m_start_packet.app_image_size,
                                  0);

    if (err_code == NRF_SUCCESS)
    {
        dfu_update_status_t update_status;

        memset(&update_status, 0, sizeof(dfu_update_status_t ));
        update_status.status_code = DFU_UPDATE_APP_COMPLETE;
        update_status.app_crc     = m_image_crc;
        update_status.app_size    = m_start_packet.app_image_size;

        bootloader_dfu_update_process(update_status);
    }

    return err_code;
}
Exemple #2
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;
}
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;
}
Exemple #4
0
void dfu_reset(void)
{
    dfu_update_status_t update_status;

    update_status.status_code = DFU_RESET;

    bootloader_dfu_update_process(update_status);
}
Exemple #5
0
/**@brief Function for handling the DFU timeout.
 *
 * @param[in] p_context The timeout context.
 */
static void dfu_timeout_handler(void * p_context)
{
    UNUSED_PARAMETER(p_context);
    dfu_update_status_t update_status;

    m_dfu_timed_out           = true;
    update_status.status_code = DFU_TIMEOUT;

    bootloader_dfu_update_process(update_status);
}
uint32_t bootloader_dfu_sd_update_finalize(void)
{
    dfu_update_status_t update_status = {DFU_UPDATE_SD_SWAPPED, };

    bootloader_dfu_update_process(update_status);

    wait_for_events();

    return NRF_SUCCESS;
}
Exemple #7
0
uint32_t dfu_image_activate (void)
{
    uint32_t            err_code = NRF_SUCCESS;
    dfu_update_status_t update_status;

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

            if (IS_UPDATING_SD()) //lint !e655 suppress Lint Warning 655: Bit-wise operations
            {
                update_status.sd_image_size = m_start_packet.sd_image_size;
            }
            else
            {
                update_status.sd_image_size = NEW_IMAGE_SIZE_EMPTY;
            }

            if (IS_UPDATING_BL()) //lint !e655 suppress Lint Warning 655: Bit-wise operations
            {
                update_status.bl_image_size = m_start_packet.bl_image_size;
            }
            else
            {
                update_status.bl_image_size = NEW_IMAGE_SIZE_EMPTY;
            }

            if (IS_UPDATING_APP()) //lint !e655 suppress Lint Warning 655: Bit-wise operations
            {
                update_status.ap_image_size = m_start_packet.app_image_size;
            }
            else
            {
                update_status.ap_image_size = NEW_IMAGE_SIZE_EMPTY;
            }

            update_status.status_code = DFU_UPDATE_NEW_IMAGES;
            update_status.bank_used = m_active_bank;
            update_status.src_image_address = dfu_storage_start_address_get();
            bootloader_dfu_update_process(update_status);

            break;

        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }

    return err_code;
}
Exemple #8
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;
}
Exemple #9
0
/**@brief Function for activating received Bootloader image.
 *
 *  @note This function will not move the bootloader image.
 *        The bootloader settings will be marked as Bootloader update complete and the swapping of
 *        current bootloader will occur after system reset.
 *
 * @return NRF_SUCCESS on success.
 */
static uint32_t dfu_activate_bl(void)
{
    dfu_update_status_t update_status;

    update_status.status_code = DFU_UPDATE_BOOT_COMPLETE;
    update_status.app_crc     = m_image_crc;
    update_status.sd_size     = m_start_packet.sd_image_size;
    update_status.bl_size     = m_start_packet.bl_image_size;
    update_status.app_size    = m_start_packet.app_image_size;

    bootloader_dfu_update_process(update_status);

    return NRF_SUCCESS;
}
Exemple #10
0
/**@brief Function for activating received Application image.
 *
 *  @details This function will move the received application image fram swap (bank 1) to
 *           application area (bank 0).
 *
 * @return NRF_SUCCESS on success. Error code otherwise.
 */
static uint32_t dfu_activate_app(void)
{
    uint32_t            err_code = NRF_SUCCESS;
    dfu_update_status_t update_status;

    memset(&update_status, 0, sizeof(dfu_update_status_t ));
    update_status.status_code = DFU_UPDATE_APP_COMPLETE;
    update_status.app_crc     = m_image_crc;
    update_status.app_size    = m_start_packet.app_image_size;

    bootloader_dfu_update_process(update_status);

    return err_code;
}
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;
    dfu_update_status_t update_status;
    
    switch (m_dfu_state)
    {    
        case DFU_STATE_WAIT_4_ACTIVATE:            
            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);        
            err_code = NRF_SUCCESS;
            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;    
}
Exemple #14
0
/**@brief   Function for handling behaviour when clear operation has completed.
 */
static void dfu_cleared_func_app(void)
{
    dfu_update_status_t update_status = {DFU_BANK_0_ERASED, };
    bootloader_dfu_update_process(update_status);
}
/**@brief Function for the Application's S110 SoftDevice event handler.
 *
 * @param[in] p_ble_evt S110 SoftDevice event.
 */
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t                              err_code;
    ble_gatts_rw_authorize_reply_params_t auth_reply;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO);

            PUTS("Connected");

            m_conn_handle    = p_ble_evt->evt.gap_evt.conn_handle;
            m_is_advertising = false;
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            {
                uint8_t  sys_attr[128];
                uint16_t sys_attr_len = sizeof(sys_attr);
            
                PUTS("Disconnected");

                nrf_gpio_pin_set(CONNECTED_LED_PIN_NO);
        
                m_direct_adv_cnt = APP_DIRECTED_ADV_TIMEOUT;

                err_code = sd_ble_gatts_sys_attr_get(m_conn_handle, 
                                                     sys_attr, 
                                                     &sys_attr_len, 
                                                     BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);

                if ((err_code != NRF_SUCCESS) && 
                    (err_code != NRF_ERROR_NOT_FOUND)) {

                    APP_ERROR_CHECK(err_code);
                }
            }
            if (!m_tear_down_in_progress)
            {
                // The Disconnected event is because of an external event. (Link loss or
                // disconnect triggered by the DFU Controller before the firmware update was
                // complete).
                // Restart advertising so that the DFU Controller can reconnect if possible.
                advertising_start();
            }

            m_conn_handle = BLE_CONN_HANDLE_INVALID;

            break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            {
                ble_gap_sec_keyset_t keys;
                ble_gap_enc_key_t    enc_key;
                ble_gap_id_key_t     id_key;

                id_key.id_addr_info = m_ble_peer_data.addr;
                id_key.id_info      = m_ble_peer_data.irk;
                enc_key             = m_ble_peer_data.enc_key;

                keys.keys_central.p_id_key  = &id_key;
                keys.keys_central.p_enc_key = &enc_key;

                err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
                                                       BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
                                                       &m_sec_params,
                                                       &keys);
                APP_ERROR_CHECK(err_code);
            }
            break;

        case BLE_GATTS_EVT_TIMEOUT:
            if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL)
            {
                err_code = sd_ble_gap_disconnect(m_conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
            }
            break;

        case BLE_GAP_EVT_TIMEOUT:
            if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
            {
                m_is_advertising = false;
                m_direct_adv_cnt--;
                if (m_direct_adv_cnt == 0)
                {
                    dfu_update_status_t update_status = {.status_code = DFU_TIMEOUT};
                    bootloader_dfu_update_process(update_status);
                }
                else
                {