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

bootloader_secure_ble example has wrong NRF_SDH_BLE_VS_UUID_COUNT

While creating a DFU bootloader based on the bootloader_secure_ble example, I was having trouble getting a device to boot into DFU mode.

Initially the device would get stuck in a reboot cycle and was unable to keep up with the logs. To mitigate this, we turned on debug mode by defining DEBUG to be 1, and added an app_error_fault_handler to the example in replacement of the app_error_handler_bare hack that was there before.

This provided us with the following symptoms

<debug> app: After nrf_dfu_transports_init
<error> app: Could not initalize DFU transport: 0x00000004
<error> app: ERROR!!!
<error> app: Error code: 0x4 
<error> app: File name: ../../main.c 
<error> app: Line number: 178 

where Line 178 in main.c was from the error check here

ret_val = nrf_bootloader_init();
APP_ERROR_CHECK(ret_val);
  • I could not find any documentation to the error from the DFU transit initialization, but by stepping through the code, the source of the error was identified as

    /**@brief     Function for checking if the CCCD of DFU Control point is configured for Notification.
     *
     * @details   This function checks if the CCCD of DFU Control Point characteristic is configured
     *            for Notification by the DFU Controller.
     *
     * @param[in] p_dfu DFU Service structure.
     *
     * @return    True if the CCCD of DFU Control Point characteristic is configured for Notification.
     *            False otherwise.
     */
    uint32_t ble_dfu_init(ble_dfu_t * p_dfu)
    {
        ble_uuid_t service_uuid;
        uint32_t   err_code;
    
        ASSERT(p_dfu != NULL);
    
        m_conn_handle = BLE_CONN_HANDLE_INVALID;
    
        BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
    
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                            &service_uuid,
                                            &(p_dfu->service_handle));
        VERIFY_SUCCESS(err_code);
    
        ble_uuid128_t const base_uuid128 =
        {
            {
                0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F,
                0x60, 0x4F, 0x15, 0xF3,  0x00, 0x00, 0xC9, 0x8E
            }
        };
    
        err_code = sd_ble_uuid_vs_add(&base_uuid128, &p_dfu->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        err_code = dfu_pkt_char_add(p_dfu);
        VERIFY_SUCCESS(err_code);
    
        err_code = dfu_ctrl_pt_add(p_dfu);
        VERIFY_SUCCESS(err_code);
    
        m_flags |= DFU_BLE_FLAG_SERVICE_INITIALIZED;
    
        return NRF_SUCCESS;
    }
    

    The first thing to notice about this function is that the description is out of date, and does not describes something quite different from what it actually does, and that the described return values are completely off. The function should always return NRF_SUCCESS at first glance, and this was not happening.

    The second thing to notice is that there is a custom BLE service being added with a UUID. Having experienced problems while implementing custom BLE services with the SDK, I went through some of our standard debugging procedures. The first step in this case was to check NRF_SDH_BLE_VS_UUID_COUNT to make sure we are reserving enough RAM in the softdevice for this custom service.

    The value was set to the default 0 when it should have been 1! After changing this value, and adjusting the RAM start and length in the linker file, the device was able to start into DfuMode successfully.

  • Actually we don't use NRF_SDH_BLE_VS_UUID_COUNT in the code of the bootloader (because nrf_sdh_ble_default_cfg_set() is never called)

    But it's a bug that we didn't configure ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count correctly when we enable the softdevice in ble_stack_init() in nrf_ble_dfu.c.

    We will report this issue internally.

  • Ok,

    But since I am compiling the bootloader and nrf_ble_dfu.c together, the call to nrf_sdh_ble_default_cfg_set() is getting the correct value from the app_config.h file of our bootloader.

    Looks like my workaround is only working due to coincidence, so thanks for following up. Could you please keep me posted here as to how this issue will be fixed on the next update? That way I can make sure my hotfix will be compatible with the next version.

Related