This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

dfu bootloop in custom application

I'm trying to implement the DFU Feature into my application, but it seems to be in a bootloop after it starts advertising. The application works fine when flashing it via nRF Toolbox, but after implementing the DFU-Service nothing works.

So far I've added the Source/Header-Files for the DFU, added a reset prepare function

void reset_prepare(void)
{
uint32_t err_code;
if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
{
    // Disconnect from peer.
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    APP_ERROR_CHECK(err_code);
    err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);
}
else
{
    // Stop the advertising.
    sd_ble_gap_adv_stop();
}
err_code = ble_conn_params_stop();
APP_ERROR_CHECK(err_code);
nrf_delay_ms(500);
}

set up a DFU Service

ble_dfu_t m_dfus;	
// ....... //
void bootloader_svc_init()
{
uint32_t   err_code;
ble_dfu_init_t   dfus_init;

// Initialize the Device Firmware Update Service.
memset(&dfus_init, 0, sizeof(dfus_init));

dfus_init.evt_handler   = dfu_app_on_dfu_evt;
dfus_init.error_handler = NULL;
dfus_init.evt_handler   = dfu_app_on_dfu_evt;
dfus_init.revision      = DFU_REVISION;

err_code = ble_dfu_init(&m_dfus, &dfus_init);
APP_ERROR_CHECK(err_code);

dfu_app_reset_prepare_set(reset_prepare);
dfu_app_dm_appl_instance_set(m_app_handle);
}

added #define IS_SRVC_CHANGED_CHARACT_PRESENT 1, edited #define DM_GATT_CCCD_COUNT 4 and #define DEVICE_MANAGER_APP_CONTEXT_SIZE 16 and call ble_dfu_on_ble_evt(&m_dfus, p_ble_evt); in ble_evt_dispatch.

I've also defined BLE_DFU_APP_SUPPORTin my project options to implement the app_context_load in my device_manager_evt_handler.

void app_context_load(dm_handle_t const * p_handle)
{
uint32_t                 err_code;
static uint32_t          context_data;
dm_application_context_t context;

context.len    = sizeof(context_data);
context.p_data = (uint8_t *)&context_data;

err_code = dm_application_context_get(p_handle, &context);
if (err_code == NRF_SUCCESS)
{
    // Send Service Changed Indication if ATT table has changed.
    if ((context_data & (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS)) != 0)
    {
        err_code = sd_ble_gatts_service_changed(m_conn_handle, APP_SERVICE_HANDLE_START, BLE_HANDLE_MAX);
        if ((err_code != NRF_SUCCESS) &&
            (err_code != BLE_ERROR_INVALID_CONN_HANDLE) &&
            (err_code != NRF_ERROR_INVALID_STATE) &&
            (err_code != BLE_ERROR_NO_TX_PACKETS) &&
            (err_code != NRF_ERROR_BUSY) &&
            (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
        {
            APP_ERROR_HANDLER(err_code);
        }
    }

    err_code = dm_application_context_delete(p_handle);
    APP_ERROR_CHECK(err_code);
}
else if (err_code == DM_NO_APP_CONTEXT)
{
    // No context available. Ignore.
}
else
{
    APP_ERROR_HANDLER(err_code);
}
}

As far as I can see, I've copied everything relevant from the ble_hrs_example to my project but it bootloops after starting advertisement. Did I miss something? When I remove the service registration (bootloader_svc_init) everything works normally. When I remove my own services and just initialize the bootloader-service it also works just fine. But the UUIDs are totally different...

Related