Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Adding Buttonless DFU service to an existing application: GATT Timeout error while trying to write ENTER_BOOTLOADER command

Hi,

I'm trying to implement Buttonless DFU into an existing BLE application. I'm using nRF52832 V1.1.0 boards (one for the BLE peripheral running the application and buttonless DFU service and another one to run nRFConnect firmware on), SoftDevice 132v6.0 and SDK15.0.

First, I followed the steps described here: https://www.nordicsemi.com/DocLib/Content/SDK_Doc/nRF5_SDK/v15-0-0/service_dfu, "Adding Buttonless Secure DFU Service to a BLE application". In order the add Buttonless Secure DFU Service to the existing application.

After that, I followed the steps described here: https://github.com/gamnes/nRF52832-buttonless-dfu-development-tutorial, in order to a) create our own bootloader using our own private/public key pair, b) Create our own FW.zip package which we can upload to the device over wireless DFU and c) Create a product release image including all components. Both b) and c) use an application.hex file generated from the extended BLE application with the Buttonless DFU service added as described above. Ultimately, I was able to flash all components (bootloader and correct settings generated in c), softdevice and application) onto one of the nRF52 boards. I then flashed the other one with the nRF Connect app firmware and was able to connect with the BLE peripheral board. I could see both the custom service (which is associated with the already existing BLE application) and the DFU service, as shown below:

I then click the DFU button also shown and tried to flash the zip.file generated in b), which contains the softdevice + application with updated adv name, in order to be able to double check the update's success. However, after waiting some time (and the nRF connect app being stuck at "initializing"), I get the following error message:

Since then, I've been trying to find the solution to this problem... I've tried adding some things that are not in my application but are in the buttonless DFU BLE example code, such as:

  • Setting BLE_DFU_ENABLED from 0 to 1. Seems logical to do so, as it is said in the comments that in such a way, I enable DFU Service. But this is not described in the documentation as part of adding the DFU service to an existing BLE application (https://www.nordicsemi.com/DocLib/Content/SDK_Doc/nRF5_SDK/v15-0-0/service_dfu).
  • Initialize the async SVCI interface to bootloader, in the services_init(void) method. This is also something that is done in the buttonless DFU BLE example but not described in the documentation as part of adding the DFU service to an existing BLE application. It consists of calling "ble_dfu_buttonless_async_svci_init()". However, when I implement this, my code is stuck in the internal SVC method "sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0])" and thus doesn't work at all anymore... I'm not sure if I need to add this, and if so, what else I need to do to get it working this way?

So, to summarize, so far my efforts to find the solution have been in vain. I'm at a bit of a loss here and don't know at all what else I'm missing / doing wrong.

Thank you in advance for having a look at this question and assisting me in finding a solution.

Kind regards,

Mathias

  • Hi Mathias, 

    You're using nRF52 DK boards?

    Make sure that you have the following Preprocessor Definitions set in KEIL project settings

     BL_SETTINGS_ACCESS_ONLY BOARD_PCA10040 CONFIG_GPIO_AS_PINRESET FLOAT_ABI_HARD NRF52 NRF52832_XXAA NRF52_PAN_74 NRF_DFU_SVCI_ENABLED NRF_DFU_TRANSPORT_BLE=1 NRF_SD_BLE_API_VERSION=6 S132 SOFTDEVICE_PRESENT SWI_DISABLE0 __HEAP_SIZE=8192 __STACK_SIZE=8192

    As for the async interface, this should be initialized as its used in the buttonless DFU service code. The sd_softdevice_vector_table_base_set() call should not hang unless you've not flashed the SD, which you've clearly done as the application code is running and you can connect to your nRF52 board. 

    Would it be possible for you to share the project ( just zip the project folder) so that I can debug the project on my end?

    Best regards

    Bjørn 

  • Hi Bjorn,

    I can share the project with you, but preferably not publicly on this thread. Is there anyway that I could email it to you somehow?

    Kind regards,

    Mathias

  • HI Mathias, I've made the case private so its only visible to Nordic Tech. Support and you, so you can upload the code here. 

  • Hi Bjørn,

    Thank you for making the case private. I've also check the Preprocessor Definitions you mentioned and two of them were not there: BL_SETTINGS_ACCESS_ONLY and CONFIG_GPIO_AS_PINRESET. I added them but it had no effect.

    You can find the code here: ... . To be able to compile, the folder should be placed in SDK15.0-Location/examples.

    Thanks again for your help.

    Kind regards,

    Mathias

  • Hi Mathias,

    I had some compilation issues with the attached example. 

    I had to add the following include statements to main.c and add ..\..\..\..\..\..\components\ble\ble_radio_notification to the include path 

    #include "ble_radio_notification.h"
    #include "SEGGER_RTT.h"

    I also had to define ATSAM_D1 and ATSAM_D2, I just defined them to two unused pins on the nRF52 DK. 

    #define ATSAM_D1 28
    #define ATSAM_D2 29

    Lastly, I had to add 

    #include "nrf_nvic.h"

    to ble_radio_notification.h in order to remove the undefined reference errors to sd_nvic_-functions. 

    In order to get the BLE stack to correctly initialize I also had to change the application ram start address from 0x20002AA8 to 0x2002F90. While adjusting the RAM start address I also noticed that the ROM size for the application was set to 0x5A000, i.e. the application uses the entire flash from 0x26000 to 0x80000. In order to fit the bootloader together with the application this need to be adjusted to 0x52000 ( Bootloader Start Address(0x78000) - Application Start address(0x26000) = 0x52000). 

    After sorting that I un-commented the code in services_init() that initializes the async SVCI interface. As you've stated after compiling in ble_dfu_buttonless_async_svci_init() the code hangs. Stepping though the code I saw that it actually got stuck after calling the NRF_LOG_INFO macro in the first nrf_dfu_svci_vector_table_set() call. 

    Since you're using SEGGER_RTT_WriteString directly instead of the NRF_LOG_ - macros I disabled the logging module by setting

    #define NRF_LOG_ENABLED 0

    in sdk_config.h. After recompiling the application I generated a new key pair, put the public key in the bootloader code, compiled and flashed the bootloader, generated a new settings hex file with the application hex as input in nrfutil and finally generate a new .zip package that is signed with the private key. 

    I used nRF Connect for Desktop to perform a DFU with the newly created .zip package and the DFU was successful. I also did multiple subsequent DFUs with the same package and all were successful. 

    I've attached a zip with the modified project in addition to the keypair, the zip package and the bootloader hex with the public key compiled in, see pkg_keys_hex_dfu.zip

Related