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

What happens after switching to Bootloader/DFU mode?

Hello again,

I'm working with the ble_app_hrs example application with DFU app support. I'm following the DFU procedure and I've reached the point where I actually start the DFU process. At this point the application starts the bootloader.

My question is: What happens at this point? This is what I understand so far:

  • I write 0x01,0x04 to the DFU Control Point.
  • The DFU forwards a BLE_DFU_START event to the dfu_app_handler.
  • The event type is checked in the handler. If it's BLE_DFU_START it starts the bootloader.

After this, I have no idea what happens.

I have a few observations:

  • The 0x04 I wrote to the Control Point is saved, but not used. See here:

     case OP_CODE_START_DFU:
         SEGGER_RTT_WriteString(0,"Received ctrl_pt: Start DFU\n");
         ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
    
         if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
         {
             SEGGER_RTT_WriteString(0,"Operation failed\n");
             return ble_dfu_response_send(p_dfu,
                                          (ble_dfu_procedure_t) p_ble_write_evt->data[0],
                                          BLE_DFU_RESP_VAL_OPER_FAILED);
         }
    
         ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
         ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
    
         p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
         break;
    

p_dfu->evt_handler is the function below:

void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    switch (p_evt->ble_dfu_evt_type)
    {
        case BLE_DFU_START:
            // Starting the bootloader - will cause reset.
            bootloader_start(p_dfu->conn_handle);
            break;

        default:
            {
                // Unsupported event received from DFU Service. 
                // Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
                uint32_t err_code = ble_dfu_response_send(p_dfu,
                                                          BLE_DFU_START_PROCEDURE,
                                                          BLE_DFU_RESP_VAL_NOT_SUPPORTED);
                APP_ERROR_CHECK(err_code);
            }
            break;
    }
}

As you can see, there's is no use whatsoever of ble_dfu_evt.evt.ble_dfu_pkt_write.p_data.

  • How does the bootloader handle everything related to the BLE DFU Service?
  • According to the documentation, after switching to DFU/Bootloader mode, I should reconnect and continue with normal DFU update. Does this include rediscovering services and characteristics, writing to CCCD and sending the 0x01,0x04 that I already sent? (I'm not using shared bonding just yet).

Thank you in advance for your support in this lengthy post :)

  • Hi Andy,

    It's not too important (and we actually ignore it) the second byte you put when you send 0x01 and 0xYY to tell the application to jump from application to the bootloader. We don't check if the 0xYY would be application or softdevice or bootloader or invalid. We simply switch to bootloader and then when the bootloader started you would need to send again the correct 0x01,0xYY to the bootloader.

    You can implement your own checking, for example if you don't accept softdevice update you can refuse to jump to bootloader if 0xYY = 0x01 or if 0xYY is not a valid opcode.

    And yes, after you jumped to the bootloader, you start doing DFU as normal, rediscovering service, write to CCCD, and write to Control Point what you want to update, init data , etc

Related