SDK13 Buttonless DFU Service doesnt change into Bootloader

Hi to everybody,

I am working with a custom board based on the nrf52832, while trying to integrate to my existing application the DFU functionality I am having problems when I try to change from app to bootloader through Buttonless DFU Service.

I follow this steps:

(nrf Studio)

  • Erase chip.
  • Program SoftDevice (s132_nrf52_4.0.2_softdevice.hex)
  • Program my modified Bootloader based on bootloader_secure_ble example.

(nrfToolbox Android)

  • Download my application with Buttonless DFU Service Integrated.

(nrfConnect V2.0)

  • Discover my device and connect.
  • Scan Services (Buttolenss DFU Service is OK)
  • Subscribe for indications.
  • Write 0x01 into the characteristic.

When I follow this steps I see how the nrfConnect receives the indication from the device with "20-01-01" data and after that "Disconnected from device F7:91:6A:2B:B8:D8, reason: BLE_HCI_CONNECTION_TIMEOUT".

This leads to a reboot on the the device but it does not start into the bootloader, it starts the app. Why is not entering into the bootloader?

If I write into the Buttonless DFU Service characteristics any value that is not 0x01 I can see on my logs this messages:

:INF:ble_dfu_on_ble_evt --> Write

:INF:Received indication state 1, notification state 0 BLE:INF:Indication for BLE_DFU is enabled.

:INF:ble_dfu_on_ble_evt --> RW Authorize Req.

:INF:on_ctrlpt_write: indication enabled

:INF:on_ctrlpt_write: execute enter

:INF:sd_ble_gatts_hvx retval = 0

:INF:ble_dfu_on_ble_evt --> HVC

:INF:is_waiting_for_reset = 0

But when the written values corresponds with 0x01 I can see how the device receives the ble_dfu_on_ble_evt --> HVC:

:INF:ble_dfu_on_ble_evt --> Write

:INF:Received indication state 1, notification state 0 BLE:INF:Indication for BLE_DFU is enabled.

:INF:ble_dfu_on_ble_evt --> RW Authorize Req.

:INF:on_ctrlpt_write: indication enabled

:INF:on_ctrlpt_write: execute enter

:DEB:on_ctrlpt_write: execuing!!

:INF:enter_bootloader --> is_waiting_for_reset = true

:INF:sd_ble_gatts_hvx retval = 0

I don't know if this is due to the reset that is performed to enter into the bootloader that doesn't let the log messages going out or is part of the issue.

My app is developed with freertos, it uses watchdog and also NRF Log messages trough a dedicated task.

The changes I have made into the bootloader_secure_ble are:

  • main.c: Delete leds_init() & buttons_init() functions.
  • nrf_dfu.c: nrf_dfu_enter_check(). Delete button check to enter bootloader
  • nrf_ble_duf.c: advertising_init() & gap_params_init() fucntions to set a custom device name using NRF_FICR->DEVICEID.

Changes made for integrating the Buttonless DFU Service into my app:

  • ble_dfu.c: added NRF_LOG_INFO messages to trace.

Inside my BLE task *.c file added:

  • Inside ble_evt_dispatch() the ble_dfu_on_ble_evt() function.

  • ble_dfu_evt_handler() handler function.

  • Inside services_ini() service creation/initilization:

    memset(&dfus_init, 0, sizeof(dfus_init));
    dfus_init.evt_handler = ble_dfu_evt_handler; dfus_init.ctrl_point_security_req_write_perm = SEC_SIGNED; dfus_init.ctrl_point_security_req_cccd_write_perm = SEC_SIGNED;

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

  • *.icf memory regions:

    define symbol ICFEDIT_intvec_start = 0x1f000;

    define symbol ICFEDIT_region_ROM_start = 0x1f000;

    define symbol ICFEDIT_region_ROM_end = 0x77fff;

    define symbol ICFEDIT_region_RAM_start = 0x20002060;

    define symbol ICFEDIT_region_RAM_end = 0x2000ffff;

    export symbol ICFEDIT_region_RAM_start;

    export symbol ICFEDIT_region_RAM_end;

    define symbol ICFEDIT_size_cstack = 0x800;

    define symbol ICFEDIT_size_heap = 0x200;

And I think I don't forget anything, so If somebody know the reason why my device is not entering properly into the bootloader after a correct DFU application download and subscribing to application's Buttonless DFU service indication and wrinting 0x01into it, please let me know if there is something missing or mistaken because I am stucked adding the DFU functionality to my app.

Thanks in advance for everyone and sorry for the long post/question.

  • After some test I have made, The device is resetting properly with the write of 0x01 into the Buttonless DFU characteristic. And I have also confirmed that the GPREGRET values is set to 0xB1.

    I am resetting the device letting the watchdog to expire because I read in section H that the watchdog continues working after a NVIC_SystemReset() call.

    In any case, it continues restarting without entering bootloader mode, it starts the application.

    Any help about configuring the secure bootloader example to enable logs through the jlink and continue digging? Any advice to check what can be occuring into the bootloader to skip into the application directly?

    Thanks in advance.

  • Can you debug the bootloader, set a breakpoint in nrf_dfu_enter_check() in nrf_dfu.cand verify whether the bootloader reaches this function or not?

  • I can't debug bootloader neither see the logs through jlink. Is there any tutorial or post about how to enable this? thanks in advance for your help.

  • You should be able to debug the bootloader with out any modifications to the project, could you try to flash the dedicated debug example to your device, i.e. the one found inexamples\dfu\bootloader_secure_ble\pca10040_debug and see if that helps?

  • I have been testing with debug bootloader.

    I dont know how to debug or see jlink log messages from the bootloader once I program the SD+BL+APP+SETTINGS over nrfjprog.

    In one of my test I have seen how after writing 01 to buttonless DFU characteristic the app reboots and in the logs of the bootloader it sends "Application sent bootloader request", but it doent stay at bootloader, it runs application.

    Any help in how to debug this situation or any configuration that could be mistaken? Thanks