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
  • Hi,

    You are right that there are a lot of changes between SDK 14 and SDK 15. Particularly the bootloader was significantly modified, so unfortunately it is difficult to isolate all changes. DFU is typically not performed very often by the end customer so I suggest you consider sticking with the current bootloader. Alternatively, migrating to the full SDK 15.2 bootloader could be an option.

  • I agree that ideally we would rarely need to do firmware updates. But the reality is that we will likely need customers to be able to do it at some point, and three minutes per device is a pretty tough ask of our users when some users may be managing tens or more of our devices. And I currently have a small window where bootloader changes are much easier to make than they will be going forward, so I'm hoping to get some optimizations in now.

    So a few questions on the topic.
    1) It seems like it shouldn't be that difficult to get MTU and DLE negotiation working on the SDK14 bootloader. But even if I can get it working, would DFU transfer speed even benefit? Or does the bootloader also need the other changes from SDK15+ to benefit from longer MTUs and DLE?
    2) Porting our application to SDK15.2 is probably quite a bit more work than just porting over our bootloader, so I'd really like to avoid going down that route if possible. So if our application is SDK14 with S132 v5.0.0, would there be any issues trying to use an SDK15.2 bootloader that must also use S132 v5.0.0?
    3) Related to 2, would there be any concerns about running an application based on SDK14 but a bootloader based on SDK15.2?

Reply
  • I agree that ideally we would rarely need to do firmware updates. But the reality is that we will likely need customers to be able to do it at some point, and three minutes per device is a pretty tough ask of our users when some users may be managing tens or more of our devices. And I currently have a small window where bootloader changes are much easier to make than they will be going forward, so I'm hoping to get some optimizations in now.

    So a few questions on the topic.
    1) It seems like it shouldn't be that difficult to get MTU and DLE negotiation working on the SDK14 bootloader. But even if I can get it working, would DFU transfer speed even benefit? Or does the bootloader also need the other changes from SDK15+ to benefit from longer MTUs and DLE?
    2) Porting our application to SDK15.2 is probably quite a bit more work than just porting over our bootloader, so I'd really like to avoid going down that route if possible. So if our application is SDK14 with S132 v5.0.0, would there be any issues trying to use an SDK15.2 bootloader that must also use S132 v5.0.0?
    3) Related to 2, would there be any concerns about running an application based on SDK14 but a bootloader based on SDK15.2?

Children
  • Hi,

    1) Using larger MTU and DLE is not enough to get to the same speeds as the bootloader from SDK 15. The request handling library was entirely rewritten to be more efficient. The buffer management in the SDK 14 bootloader is the main bottleneck that was improved.

    2) If you want to use the SDK 15.2 bootloader, then I suspect it is easier to migrate the application as well. The alternative is as you write, to migrate the SDK 15.2 bootloader to S132 version 5, but I am not convinced that it will be less work.

    3) It is definitely possible to use an application based on SDK 14 and a bootloader based on SDK 15.2. However, that means that you have to migrate one of them to a different SoftDevice API, and there have been significant changes. There are also a few other changes related to buttonless DFU, bond sharing etc. that you may need to account for.

    Without knowing details of your application, I would assume that the effort put in to migrating the application to a new SDK version or bootloader to a different SoftDevice version is similar, and then it seems to me that migrating your application to SDK 15.2 is the best solution (unless you just stick with everything from SDK 14, including a slower bootloader).

  • Thanks. This isn't the answer I was hoping for, but it is the clarification I needed. I'm going to take a day or so to see how much work it will be to just port my whole project over to SDK 15.2, but I have a feeling I'm going to end up just sticking with SDK 14 across the board.

    Do you have any idea how much faster the SDK15+ BLE bootloader updates have made the transfer process?

  • For me, an update that used to take roughly 1.5 minutes now finishes in 15 seconds.

  • But I migrated from SDK 13, I don't know what the performance of SDK 14 is.

  • Good to know. Do you know the data rate you're getting on the transfer with SDK15? Or do you know how big your firmware image is?

Related