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

Bonding issue with DFU BLE on custom board with SDK v10 and SD v8.0

In nutshell, I intend to achieve

Buttonless DFU over BLE on a custom board with SDK v10.0.0 and Softdevice v8.0.0 with bonding retained.

On this custom board, there are neither any buttons nor any external clock, hence I had to make corresponding changes in the sample bootloader (that comes with SDK v10.0.0) and in my application. Currently DFU over BLE is working (triggering DFU from bootloader and/or triggering DFU from the application), but the bonding is getting removed after DFU is completed (see the snip from the MCP logs below)

A 16:11:58.706 [DFU] Activate and Reset request sent
I 16:11:58.949 [DFU] Disconnected by the remote device
D 16:11:58.976 [DFU] gatt.refresh() (hidden)
D 16:11:59.102 [DFU] gatt.close()
V 16:11:59.150 [DFU] Removing bond information...
D 16:11:59.183 [DFU] gatt.getDevice().removeBond() (hidden)
D 16:11:59.244 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
D 16:11:59.299 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_NONE (10)
I 16:11:59.335 Bond information deleted

Enviornment:

  • SD: v8.0.0
  • SDK: v10.0.0
  • SOC: nrf51822QFAA
  • SOC IC revision: 2
  • Central Application for testing DFU BLE: Nordic's Android phone app, MCP

According to the Compatibility matrix, IC revision 2 is not supported on SDK v10.0.0, but I was told by a Nordic Employee in this thead , that IC revision 2 could also work with SDK v10.0.0 and such efforts are best left to the customers to validate. So, I started porting the application (Bond sharing between Bootloader and Application was not possible with sdk v6.1.0 and SD v7.1.0). The application was ported fine and I did some basic connectivity, and services related tests and it worked well. Now during the DFU over BLE, I face this problem of bonding getting deleted. I suspect the problem is with firmware and not with the IC compatibility issue.

I've set the memory settings for Bootlader in KEIL MDK5 Toolchain, according to this thread and is as follows:

IROM1 Start: 0x0003C000 Size: 0x3C00
IRAM1 Start: 0x20002C00 Size: 0x1380
IRAM2 Start: 0x20003F80 Size: 0x80 (NoInit Checked)

And, Memory settings for application in Keil MDK5 Toolchain:

IROM1 Start: 0x18000 Size: 0x28000 (Total 256 kB main flash memory)
IRAM1 Start: 0x20002000 Size: 0x4000 (Total 16 kB of RAM) 

Some code snips from Application:

// 1: Retain bonding
bool erase_bonds = false;
device_manager_init(erase_bonds);

// 2: Low frequency internal clock source to be used by the SoftDevice
#define NRF_CLOCK_LFCLKSRC NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION

void ble_stack_init()
{
............

SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC, NULL);
............

}

// 3: Allow service change characteristics
#define IS_SRVC_CHANGED_CHARACT_PRESENT     1

In the bootloader, same clock source (NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION) is used in ble_stack_init() and I have commented out following two lines in sample Bootloader code:

//    buttons_init(); /* No buttons on this custom board */

//    dfu_start |= ((nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0) ? true: false); /* no use */

and Service changed characteristic is also set to '1':

// Allow service change characteristics
#define IS_SRVC_CHANGED_CHARACT_PRESENT     1

Setup for "dfu_ble_svc.c" in the bootloader project configuration:

image description

The complete DFU logs collected using nRFLog is attached here.

Has someone seen such behavior ? and how to fix this issue ? My gut feeling is that this is not a IC compatibility issue and I'm probably missing something important in the firmware side.

Please suggest.

Update: 27.05.2019

Attaching central and peripheral logs (please refer my last comment)

Central logs: dfu_central_logs.txt

Peripheral logs: dfu_peripheral_logs.txt

  • In order to retain the bonding data during a DFU, you have to change the value of DFU_APP_DATA_RESERVED in dfu_types.h, the default value is 0x0000.

    #define DFU_APP_DATA_RESERVED           0x0000
    

    The value refers to the to number of bytes below the Bootloader start address that should be retained. Thus, in order to retain the bonding data you have to set it as shown in the picture below. Please note that the figure assumes that you use the Persistant Storage Manager.

    image description

    If you're not using the Persistant Storage Manager, then you should only have to set DFU_APP_DATA_RESERVED to 0x400, i.e. one flash page.

    For more information see this Infocenter page.

    -Bjørn

  • @Bjørn, Thank you. I was busy doing some other stuff and hence coming back to this topic after a while. Today I tried as you suggested, and it hasn't worked yet (actually, I'm getting into another issue). So the first thing I did was corrected memory partitioning for Bootloader and application. For bootloader:

    IROM1: 0x3C000 (0x4000) <-- 16 KB for Bootloader
    IRAM1: 0x20002C00 (0x1380)
    IRAM2: 0x20003F80 (0x80) No Init box checked
    

    For application:

    IROM1: 0x18000 (0x23400)  <-- this was incorrect before
    IRAM1: 0x20002000 (0x4000)
    

    Numbers in parenthesis represent size.

    As of now I'm doing Just works pairing (Central is able to connect to the peripheral without being asked to enter any passkey) and then I do the bonding. To enable bonding, I'm using persistent storage manager. <reached size limit, continue in next comment>

  • Persistent manager:  one page.  
    Application data: one page (For future purpose)
    Swap : one page
    

    Therefore, I'm now setting DFU_APP_DATA_RESERVED to 0xC00 (Note that dfu_types.h is not included in application, hence It is only relevant when building booloader) and hence the IROM1 size value for application has been adjusted to (0x3C000 - (3 * 0x400)) - 0x18000 = 0x23400.

    But with this configuration, If i start DFU after connecting (no passkey) --> bonding --> initiating DFU (using MCP andorid app and using a .zip file containing only application), central gets disconnected in the middle of DFU and from here I re-issue DFU, which works, since the system is now in Bootloader mode already (This is the new behavior). This is even worse, as it fails in the middle of DFU and I still could not retain Bonding. All other configurations are same

  • Update

    In the presence of bootloader whose start address is 0x3C000 On my 256 KB version of NRF51822 SOC, the IROM1 field for the application should be as:

    IROM1: 0x18000 (0x24000)
    IRAM1: 0x20002000 (0x4000) <--- same as before
    

    Since, the application data, swap data, and device manager all part of application area(correct me if i'm wrong), IROM1 for application should be starting from 0x18000 until the start of bootloader start area (0x3C000)

    Also, updated PSTORAGE_NUM_OF_PAGES to '3' (device manager + application data, + swap data) in application specific pstorage_plafrom.h

    Result: DFU fails everytime (MCP error log: [DFU] Connected: DFU Service not found.)

    After this, I do a power cycle (since, the peripheral seem to be stuck somewhere and is not even advertising anymore) and then the peripheral shows up in MCP as bonded device.

  • @Bjørn, Meanwhile, I'm not able to understand what you meant by this "If you're not using the Persistant Storage Manager" Isn't device manager implemented using persistent storage manager ? i.e. If I need to retain bonding information, i need to use device manager and using device manager implicitly mean using persistent storage manager. Even the sample routine "device_manager_init() invokes "pstorage_init()"

Related