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

Buttonless DFU with bonding

Good afternoon,

I first devoloped my app based on the nRF52840 (SDK 15.2; S140 V.6.1.0) and it was perfectly working with or without bonds.

After that, and following what it is shown in this link (https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/getting-started-with-nordics-secure-dfu-bootloader), I implemented Buttonless DFU funcntionality without bonds, and it was working fine. Now, I have tried to go ahead and doing the same DFU process with bonds, but application gets stuck when initializing DFU service: it gets stopped at 'ble_dfu_buttonless_init' function, when calling 'ble_dfu_buttonless_backend_init', and the result is 0x0008 (NRF_ERROR_INVALID_STATE). In order to test DFU with bonds, I have carried out the required modifications according to information specified in the link above:

Do you know which can be the reason of such error?

Best regards,

Dani.

  • Hi Einar,

    Yes, I have the device bonded first...

    But I have more information: up to now I was doing all the tests with the LG K4 (Android 6.0.1). I have just tested the same process with a Xiami Mi6 and now the DFU process is perfectly working. But...

    What does it happen with bonding after application update? After DFU, an as it should be, my module is reseted and starts working again but, when I try to connect again with it with BLE (using the same app I normally use), it is not possible to succeed. In order to correctly connect again with it, I have to erase bonding information from the Smartphone, and then everything works. How can I manage bonding in order to avoid this situation to happen after DFU?

    I have also tried to check behavior with 'nRF Connect' tool after this succesful DFU process: as the device is already bonded, it appears in bonded list, and when I try to connect, I only am able to see the characteristics related to DFU service (but device is not working in DFU mode, as apart of BLE connection, it is perfectly working).

    Any suggestion?

    Best regards,

    Dani.

  • Hi Dani,

    Based on what you write here, it seems that the bonding information is overwritten when you do DFU. This can happen if the bootloader configuration does not match your applicaiton's configuration.

    Bonding information is handled by the peer manager library, which stores it using FDS. The FDS pages are always located immediately below the bootloader in the memory layout. The application's sdk_config.h file has a FDS_VIRTUAL_PAGES, which is typically set to 3, but you may have modified it? A page is 4 kB.

    The bootloader on the other hand, needs to be told to stay away from this memory, and not use it for temporarily storing update images (when doing dual bank updates). The bootloader's sdk_config.h file use NRF_DFU_APP_DATA_AREA_SIZE for this. This is in bytes rather than pages, so the default value of 12288 corresponds to 3 pages. If you for insstance use 5 pages in your application, the NRF_DFU_APP_DATA_AREA_SIZE should instead be set to 5*1024*4= 20480.

    Einar

  • Hi Einar,

    I'm using 4 pages in flash in order to preserve some application data.

    In what regards Application I have the following definitions:

    - FDS_VIRTUAL_PAGES 6

    - Definition of the pages where I'm saving data (I have defined 6 pages but I'm only using 4. And I think there is one page that is used by the system, right?):

    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
    {
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler,

    /* These below are the boundaries of the flash space assigned to this instance of fstorage.
    * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
    * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
    * last page of flash available to write data. */
    .start_addr = 0x000f4000,
    .end_addr = 0x000f8000,
    };

    Should I consider the other pages I'm not using in this NRF_FSTORAGE_DEF call?

    And in what regards bootloader I have:

    - NRF_DFU_APP_DATA_AREA_SIZE 24576   (6 pages)

    I have stated that Bootloader starting address is 0x000f8000. I have fixed this value but, is there any function that gives this address? (This is to have this well managed, as a problem would raise when updating softdevice and Bootloader address changes)

    So, where can I have my problem?

    Best regards,

    Dani

  • Hi Dani,

    The key here is to have a full overview of your memory layout, and once you do, the configuration becomes obvious.

    • You write that your bootloader starts at 0x000f8000. So everything above there is off limits.
    • Immediately below the bootloader, you find the FDS pages, (which use fstorage for low-level flash accesss). Is this the NRF_FSTORAGE_DEF you refer to, or do you also use this in your application directly? If so, this overlaps with the FDS pages and will cause problems.

    If you use both fstorage directly (4 pages) and FDS (6 pages) via peer manager for storing bonds, then your memory layout should look something like this:

    If this is the case and you indeed use fstorage directly, you must modify it so that it does not overlap with FDS by changing your code like this:

    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
    {
        /* Set a handler for fstorage events. */
        .evt_handler = fstorage_evt_handler,
    
        /* These below are the boundaries of the flash space assigned to this instance of fstorage.
        * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
        * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
        * last page of flash available to write data. */
        .start_addr = 0x000ee000,
        .end_addr = 0x000f2000,
    };

    And this means that your bootloader needs to stay away from 10 pages, so NRF_DFU_APP_DATA_AREA_SIZE = 10*1024*4 = 40960.

    Regarding the bootloader start address, it is whatever you set it to be in the linker settings, just as the application. And then there are a few tricks that is used to put this into the UICR register that the MBR checks. This is all done for you though, so you normally do not need to care about the details. If you are interested, you can search for "uicr_bootloader_start_address" through the SDK.

  • Hi Einar,

    First of all, thank you so much for your answers.

    First, I think that I was a bit confused with FDS and fstorage.

    Now, I use NRF_FSTORAGE_DEF in my application in the way I sent you. Do I need to do this? Do I need to define this boundaries?

    In fact, what I really want is:

    - To have 4 pages (or more) in order to preserve my application data: here I have already implemented this in order to write and read equipment parameters using functions as: nrf_fstorage_erase, nrf_fstorage_write, nrf_fstorage_read,...

    - To have enough space to save bonding information allowing the device to save bonding information for several devices to which my device is able to connect to. How can I determine how much space is required for a bonding set? How can I know the number of connections (bondings) that can be saved?

    Taking into account this information, which implementation do you reccommend me to follow in my application?

    Best regards,

    Dani.

Related