nRF51 SDK - S110 SoftDevice
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Experimental - Application with DFU Service support

This page describes how to include and use the possibility of including the DFU BLE Service into an application so that Bootloader/DFU mode can be automatically entered.
After entering Bootloader/DFU mode, a DFU Over-The-Air update can be performed.

An example application based on Heart Rate Application has been created for testing this feature. The project file for this example is located together with the existing Heart Rate example.

The name of the example is experiemental_ble_app_hrs_s110_with_dfu_pca10028. If you are not using the Keil Pack Installer, you can find the source code and project file of the example in the following folder: <InstallFolder>\Nordic\nrf51\example\ble_peripheral\ble_app_hrs

Open the project file experimental_ble_app_hrs_dfu.uvproj with Keil for testing and examine the BLE DFU Service functionality in a BLE example.

Testing

Test the DFU BLE Service support Heart Rate Application with the Master Control Panel by performing the following steps:

  1. Compile and program the application.
    • Observe that the Advertising LED is lit.
  2. Connect to the device from Master Control Panel (the device will be advertising as 'Nordic_HRM'), then perform service discovery.
    • Observe that the Connected LED is lit, and the Advertising LED is off.
  3. Enable 'DFU Notifications' by writing the value '0100' to the cccd in DFU Control Point.
  4. Writing 'Start DFU - Application update', that means the value '01-04', to the DFU Control Point.
  5. Notice that the connection to the BLE device is lost.
    • Will write 'SERVER: Received Link Loss' in the log window.
  6. Press 'Back' in Master Control Panel to enter the 'Discovered devices' overview.
  7. Clear the discovered devices and 'Start discovery'.
  8. Verify that the device is now advertising as 'DfuTarg'.
    • If sharing of bond information is shared from application to DFU, directed advertisement is used and only the bonded peer will be able to connect.
    • 'DfuTarg' will not be seen in advertisement packet when doing directed advertisement.
  9. Perform a DFU update with any test image or application.

Supporting DFU in any BLE example

Any BLE application can easily be extended to support the DFU Service, which allows nRF51 to enter DFU mode by writing 'DFU Start' to the DFU Service Control Point.

The following must be done to support entering of DFU mode from application:

  • Add DFU related files to BLE example project:
    • bootloader_util_arm.c
    • ble_dfu.c
    • dfu_app_handler.c
  • Implement the reset_prepare() function to allow application-specific operations executed for a graceful system shutdown.
  • Initialize the DFU Service.
  • Propagate SoftDevice BLE events to the DFU Service.

Including DFU files in application

When supporting the DFU BLE Service in an existing BLE application, the following procedure can be used:

  1. Open the BLE application in Keil, for example the Heart Rate example.
  2. Add a new group Dfu.
  3. Add the following files:
    • bootloader_util_arm.c, found in <InstallFolder>\Nordic\nrf51\components\libraries\bootloader_dfu
    • dfu_app_handler.c, found in <InstallFolder>\Nordic\nrf51\components\libraries\bootloader_dfu
    • ble_dfu.c, found in <InstallFolder>\Nordic\nrf51\components\ble\ble_services\ble_dfu

See figures 1-3:

dfu_existing_proj.png
Figure 1: Opening an existing Keil BLE project
dfu_add_group_proj.png
Figure 2: Adding a DFU Group to project
dfu_add_files_proj.png
Figure 3: Adding files to the DFU group

Initialising DFU Service in BLE example

To support the BLE DFU service in an application, the DFU Service must be initialized in the application.

The following code snippet shows how this is done in the Heart Rate example supporting DFU in main.c:

#include "ble_dfu.h"
#include "dfu_app_handler.h"
ble_dfu_init_t dfus_init;
// Initialize the Device Firmware Update Service.
memset(&dfus_init, 0, sizeof(dfus_init));
dfus_init.error_handler = NULL; //service_error_handler - Not used as only the switch from app to DFU mode is required and not full dfu service.
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);

Remember that for the DFU Service to function properly, all BLE Stack events from the SoftDevice must be propagated to the DFU Service by calling ble_dfu_on_ble_evt containing the event as parameter.

BLE Stack events are usually progated to sub modules in main.c in a function named ble_evt_dispatch(ble_evt_t * p_ble_evt).

ble_dfu_on_ble_evt(&m_dfus, p_ble_evt);

Bond information sharing

When supporting the DFU BLE Service in an application that uses the Device Manager, it is possible to transfer bonding information from the application to the Bootloader/DFU.

Bonding information consists of the peer address, IRK, and LTK of the connected peer.

The bonding information will be used to re-establish the secure connection between the devices.

When switching from application to Bootloader/DFU mode as described in Switching from application to Bootloader/DFU mode, the Bootloader/DFU will do directed advertisement if bonding information is available. If the peer does not reconnect to the device while doing directed advertisement, the system will reset and load the installed application again.

The keys needed to re-establish the secure connection can be retrieved using dm_distributed_keys_get. After retrieving the keys from the Device Manager, they must be passed to the Bootloader/DFU.

err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
APP_ERROR_CHECK(err_code);
m_peer_data.addr = key_set.keys_central.p_id_key->id_addr_info;
m_peer_data.enc_info = *key_set.keys_central.enc_key.p_enc_info;
m_peer_data.irk = key_set.keys_central.p_id_key->id_info;
err_code = dfu_ble_svc_set_peer_data(&m_peer_data);
APP_ERROR_CHECK(err_code);
Note
To use the SVC function in Bootloader/DFU, the application SVCs must be forwarded correctly. This is done by calling sd_softdevice_vector_table_base_set with NRF_UICR->BOOTLOADERADDR as argument.
Currently only directed advertisement is supported. Use of IRK and whitelist advertisement in Bootloader/DFU is not available.
Warning
If the installed bootloader/DFU on the device does not implement an SVC handler and the application tries to call dfu_ble_svc_set_peer_data, the system will end in the default SVC handler, which is an infite loop.

Switching from application to Bootloader/DFU mode

Before switching from application to bootloader/DFU mode for receiving a new firmware image, it might be important for the current application to shut down gracefully.

To support a graceful shutdown, the dfu_app_handler.c supports a reset_prepare function to be implemented in the application. This function will be executed prior to the reset and allows the application to perform any tasks considered important prior to reset.

Be aware that the reset will not occur until the reset_prepare function returns.

Such tasks could be:

  • Gracefully disconnect and close any active BLE links
  • Wait for pending flash operation to finish to ensure known state
  • Cleanup registers
  • Other

In main.c of the Heart Rate example, the prepare function contains:

  • Graceful disconnect and closure of BLE links or advertising stop if no open connections
  • Turning off LEDs

Example of Reset prepare implementation:

static 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);
APP_ERROR_CHECK(err_code);
}
else
{
// If not connected, then the device will be advertising. Hence stop the advertising.
advertising_stop();
}
err_code = ble_conn_params_stop();
APP_ERROR_CHECK(err_code);
}

Switching from running the application into Bootloader/DFU mode is done through writing to the control point of the DFU Service. See DFU Control Point for further details.

The below flowchart shows the basic principle of switching from running a BLE Application to run the Bootloader/DFU.

ota_dfu_buttonless.png
Figure 4: Switching from application to Bootloader/DFU mode

After entering Bootloader/DFU mode, a SoftDevice, Bootloader, or Application can be transfered Over-the-Air as described in Device Firmware Update over BLE.

Note
No acknowledgement will be sent when writing the Control Point with 'Start DFU' operation code. The system will close the connection and silently switch to Bootloader/DFU mode.