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 Bjørn,

    First of all, thank you so much for taking the time and effort to get to the solution.

    My apologies for the compilation issues. I forgot that we had to add '#include "nrf_nvic.h' to the "ble_radio_notification.h" file, it's already some time ago that we did that... 

    In terms of adding #include "ble_radio_notification.h" and #include "SEGGER_RTT.h" to the main, we weirdly enough never had issues with it (we only get warnings when compiling, no errors =>  ..\..\..\main.c(1064): warning:  #223-D: function "ble_radio_notification_init" declared implicitly, ..\..\..\main.c(1026): warning:  #223-D: function "SEGGER_RTT_WriteString" declared implicitly). The fact that '..\..\..\..\..\..\components\ble\ble_radio_notification' wasn't added to the include path, surprises me as well. I've done other projects were I did get issues not adding it.

    ATSAM_D1 and ATSAM_D2 are indeed two defines we added to our pca10040.h file, so also apologies for forgetting to mention that.

    In terms of the RAM address, we got the 0x20002AA8 start value from debugging the nrf_sdh_ble_enable method. But I think I also forgot to mention here that in our project, NRF_SDH_BLE_GATT_MAX_MTU_SIZE is 247 and NRF_SDH_BLE_VS_UUID_COUNT is 2. But these are SDK_config defines so I guess they should also have been these values when you compiled it as well.

    I was able to get the DFU working now as well, by indeed changing NRF_LOG_ENABLED to 0. However, I didn't have to change the ROM size on my side. Is this really a necessary aspect?

    So just to be clear, apart from what the documentation guide for adding the DFU service to an existing application shows, the necessary other steps to do are:

    • Setting BLE_DFU_ENABLED to 1
    • Initializing the async SVCI interface to the bootloader
    • Change the ROM size settings?

    Am I correct?

    Thanks again for all your help in finding the solution, I really appreciate it.

    Kind regards,

    Mathias

  • Hi Mathias, 

    •  Yes, you need to add the following preprocessor definitions
      • NRF_DFU_SVCI_ENABLED
      • NRF_DFU_TRANSPORT_BLE=1
    • You need to initialize the async SVCI interface
    • Yes, if the application start address(IROM1 Start) +  Memory block size(IROM1 Size) == 0x80000 (256kB), then there is no space left for the bootloader, which starts at address 0x78000. 

    Bjørn

  • Hi Bjørn,

    Thanks for answering. Apologies for stressing on these things, but I'd like to be sure of what needs to be done so that in the future, I can add DFU to other applications without further issues:

    • Ok, so definitely these preprocessor definitions. But do you I also need to set BLE_DFU_ENABLED to 1 in de SDK config?
    • Ok, I understand.
    • Ok, but can it be that such a changing of the size in Keil, only defines a maximum? Because our application is much smaller than 0x52000. I've read the memory of the device using nRF Connect Programmer, both when the ROM size was set to 0x52000 and when it was 0x5A000. The memory layout stays the same, with my application size being only 37164 bytes. I'm I correct in saying its just a formal definition of a maximum for the compiling? In other words, as long as my application doesn't exceed 0x52000 in reality, it won't be a problem either way when working together with bootloader?

    Also, I don't fully understand why calling the NRF_LOG_INFO macro would hang my code? I indeed never used the NRF_LOG macros in the past, but I also never had to change NRF_LOG_ENABLED to 0 in order to ensure my code doesn't hang on these macro's. I've done projects in the past with the Nordic SDK and boards and there were a lot of NRF_LOG_INFO 's still there in the code, unused, but they didn't hang my code. So I don't get why it would do that now? Sorry if this is a stupid question but I would like to avoid this problem in the future so I'd like to understand why it happened.

    Thanks again.

    Kind regards,

    Mathias

  • Hi Mathias, 

    Its not strictly needed as BLE_DFU_ENABLED is not referenced in ble_dfu.c, ble_dfu_unbonded.c, ble_dfu_bonded or nrf_dfu_svci.c. However, just set it equal to 1, better safe than sorry. 

    Great.

    You are correct that if your application is smaller than 0x52000 bytes, then there is no issue. However, its considered good practice to define the limits of you application so that it does not overlap other memory segments.  

    Segger RTT is used by the nRF_Logging module, but you're referencing the Segger_RTT_WriteString API directly instead of through the NRF_LOG_-macros. This could lead to some undefined behaviour. So either use the  NRF_LOG_ with NRF_LOG_ENABLED set to 1 OR use Segger_RTT_WriteString with NRF_LOG_ENABLED set to 0. 

    Best regards

    Bjørn

  • Hi Mathias, 

    Its not strictly needed as BLE_DFU_ENABLED is not referenced in ble_dfu.c, ble_dfu_unbonded.c, ble_dfu_bonded or nrf_dfu_svci.c. However, just set it equal to 1, better safe than sorry. 

    Great.

    You are correct that if your application is smaller than 0x52000 bytes, then there is no issue. However, its considered good practice to define the limits of you application so that it does not overlap other memory segments.  

    Segger RTT is used by the nRF_Logging module, but you're referencing the Segger_RTT_WriteString API directly instead of through the NRF_LOG_-macros. This could lead to some undefined behaviour. So either use the  NRF_LOG_ with NRF_LOG_ENABLED set to 1 OR use Segger_RTT_WriteString with NRF_LOG_ENABLED set to 0. 

    Best regards

    Bjørn

Related