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

Can the SDK15 BLE DFU speed improvements be backported to an SDK14 bootloader?

I'm using SDK14 and the nRF52832, and my bootloader is based on the BLE secure bootloader example from SDK14. I'm currently seeing transfer speeds during the secure DFU process vary from about 0.8KB/s to about 2.5KB/s depending on the device I use to send the update and whether or not I manually request a faster connection interval. My firmware image is pushing 200KB at this point, and a firmware update process that takes 2-3 minutes is getting to be an issue for us.

But I noticed in the SDK15 release notes that the DFU library was updated to use higher MTU and data length values. The release notes for SDK 15.0 say this:

> The BLE DFU bootloader will use long ATT MTUs and data length extension when the host supports these features. This increases DFU transfer speed considerably.

Can these changes be easily backported into a bootloader based on SDK14?

I've actually already tried a couple of things without any luck. First I tried just pulling the SDK15.2 bootloader library into my project and tried to resolve all the compilation issues. But it involved a seemingly endless series of pulling in other dependencies from SDK 15.2 due to changes, and I stopped when it got to a point that some files related to the SoftDevice changed between SDKs because I wondered if those libraries would even work with my existing s132 v5.0.0 softdevice.

Then I tried just pulling in the parts of the code that handle the MTU and data length negotiations. I tried the following:

  • set NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 247 in sdk_config.h
  • replace the BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event handler in SDK14's nrf_ble_dfu.c with the one from SDK15.2's nrf_dfu_ble.c since the one in SDK14 simply always replied with the default MTU value of 23.
            case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
            {
                uint16_t const mtu_requested =
                    p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu;
    
                /* If the requested MTU is smaller than the maximum, we can accept with the given
                 * stack configuration, and the payload is not word-aligned, reply with a smaller MTU
                 * that has a word-aligned payload. This ensures that the length of data we write to
                 * flash is a multiple of the word size.
                 */
                uint16_t mtu_reply;
    
                if (mtu_requested < NRF_SDH_BLE_GATT_MAX_MTU_SIZE)
                {
                    /* Round the payload size down to a multiple of 4 so it is word-aligned. */
                    if (GATT_PAYLOAD(mtu_requested) % 4)
                    {
                        mtu_reply = GATT_PAYLOAD(mtu_requested) - 4;
                        mtu_reply = ALIGN_NUM(4, mtu_reply);
                        /* Add the header len to the MTU. */
                        mtu_reply += GATT_HEADER_LEN;
                    }
                    else
                    {
                        mtu_reply = mtu_requested;
                    }
                }
                else
                {
                    mtu_reply = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
                }
    
                NRF_LOG_DEBUG("Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (request: %d, reply: %d).",
                              mtu_requested, mtu_reply);
    
                err_code = sd_ble_gatts_exchange_mtu_reply(m_conn_handle, mtu_reply);
                APP_ERROR_CHECK(err_code);
            } break;
  • copy in some supporting macros from SDK15's nrf_dfu_ble.c (GATT_PAYLOAD(), ALIGN_NUM(), etc)

However, when I do this, I get an INVALID_PARAM error when sd_ble_gatts_exchange_mtu_reply() is called in that snippet when I try to request any MTU higher than 23 using the nRF Connect Android app. In the process of trying things, I also saw sd_ble_gap_data_length_update() return the same INVALID_PARAM error, but I'm having trouble reproducing that particular error at the moment.

So before I get too deep, I thought I'd ask. Is it possible to enable the MTU and data length improvements introduced in SDK15 without substantial changes to my SDK14 bootloader? Is it even going to make much difference if I don't also have other SDK15 improvements (newer softdevice, etc)?

I've read and tried to follow this older similar thread (devzone.nordicsemi.com/.../transfer-speed-secure-dfu-sdk14), which makes it sound like the bottleneck is flash IO rather than BLE throughput. But that was before SDK15, which explicitly claims bigger MTUs and DLE speed up the transfer "considerably". So I'm not sure what to think.

Parents Reply Children
Related