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

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.

  • I have get the bootloader logs, and once the app is restarting to entre the bootloader this is what i get:

    :INF:Inside main
    :DEB:In nrf_bootloader_init
    :DEB:In real nrf_dfu_init
    :DEB:running nrf_dfu_settings_init
    :DEB:Enter nrf_dfu_continue
    :DEB:Valid App
    :DEB:Application sent bootloader request  !!!
    :DEB:In nrf_dfu_transports_init
    :DEB:num transports: 1
    :DEB:vector table: 0x00073000
    :DEB:vector table: 0x00073000
    :DEB:Error code - sd_softdevice_vector_table_base_set: 0x00000000
    :DEB:Before SOFTDEVICE_HANDLER_APPSH_INIT
    :DEB:After SOFTDEVICE_HANDLER_APPSH_INIT
    :INF:Error code - sd_ble_cfg_set: 0x00000000
    :DEB:Enabling softdevice.
    SDH:DEB:RAM start at 0x20002060.
    :DEB:Softdevice enabled
    :DEB:After nrf_dfu_transports_init
    
  • log cont'd ...

    :DEB:------- nrf_dfu_flash_init-------
    :DEB:Waiting for events
    :INF:Inside main
    :DEB:In nrf_bootloader_init
    :DEB:In real nrf_dfu_init
    :DEB:running nrf_dfu_settings_init
    :DEB:Enter nrf_dfu_continue
    :DEB:Valid App
    :DEB:Enter nrf_dfu_app_is_valid
    :DEB:Return true. App was valid
    :DEB:Enter nrf_dfu_app_is_valid
    

    So it seems that during the first restart it detect ok it must stay at bootloader but it restarts once more and this erased the order of staying at bootloader.

    The app is using the watchdog, I will modify the app to restart not by bootloader_start() function. I will use the WDT restart to see if this solves the double reboot.

    Is there any option to force a quick WDT restart or I must let the WDt to expire?

  • I have tried without success modifying bootloader_start() function:

    OPT1)

    • Set GPREGSET to 0xB1

    • NVIC_SystemReset()

    This leads to a restart where the boot loader sees:

     0> :DEB:RESETREAS: 0x00000006.
     0> :DEB:TGPREGRET: 0x000000B1.
    

    but after reaching to:

    :DEB:Waiting for events
    

    It restarts once more with:

     0> :DEB:RESETREAS: 0x00000006.
     0> :DEB:TGPREGRET: 0x00000000.
    

    So there is no bootloader DFU, the app starts normally.

  • OPT2)

    • Set GPREGSET to 0xB1

    • Force a WDT reset

    This leads to a restart where the boot loader sees:

     0> :DEB:RESETREAS: 0x00000006.
     0> :DEB:TGPREGRET: 0x00000000.
    

    The app starts normally.

    Right now I have commented sd_softdevice_disable(), sd_softdevice_vector_table_base_set() and NVIC_ClearPendingIRQ() lines because I read that with setting GPREGRET to 0xB1 and restarting is enough.

    Any help for this issue/problem?

  • If the App uses the WDT there is no possibility of reseting the app from WDT because the GPREGRET will be lost.

    I am trying to include WDT support to the secure bootloader using this post1 and this other post2 but I am still suffering the restart once the bootloader detects it must stays at bootloader DFU.

    Where is the right place to refresh the WDT at the secure bootloader? I am using SDK13.

Related