Bluetooth Low Energy (a.k.a Bluetooth LE, BTLE, Bluetooth Smart)

Internals of the Nordic DFU Bootloader

09 Jun 2015

Thanks Rohit, very much appreciated

16 Jun 2015

Hi, I've got a RedBear BLE Nano board (http://redbearlab.com/blenano/) and would like to use FOTA. I'm not sure if FOTA is possible on this board but from a previous post I read that "This bootloader should work for all nRF platforms: mkit, nRF-DK, Dongle, etc." I downloaded the bootloader image hex file in the this link (https://developer.mbed.org/media/uploads/rgrover1/default_bootloader_app_s130_tmp.hex) and copied it in to the MBED drive of my board, but the board immediately restarted and not even sure if it actually got a copy of the bootloader or not. In any case the application that I had on the board before this download still works. When I use the DFU service of the application there is a reset but the application starts again instead of the bootloader. What am I doing wrong? Has anyone used the bootloader successfuly on a BLE Nano board?

Thanks for your help, Shaadee

16 Jun 2015

Rohit,

One thing I have noticed with the FOTA updates using both the Android and iOS Nordic example apps is that DFU reliably seems to fail the first time ( on Android this is described as GATT_ERROR(133) ). Then on the second attempt to do a DFU update it succeeds. This is 100% recreatable on both iOS and Android.

Are you aware of this issue and could it be related incrementing the MAC address +1 to get around the BLE device name caching?

Thanks again,

Allen

16 Jun 2015

I don't see the failures. I've also got a version of the bootloader which doesn't do MAC address + 1. We'll be updating the online build system with this new bootloader hopefully tomorrow.

18 Jun 2015

Hi Rohit,

I’m trying to test the FOTA functionality on an mKit and on a custom board which mounts the nRF51822. I’m using the default-initial-app that you recently shared (default_bootloader_app_s130_tmp.hex). I manage to connect to the DefaultApp and to the DfuTarg with the nRF control panel, but when I try to upload the app I get the error “Remote DFU error: REMOTE DFU DATA SIZE EXCEEDS LIMIT". I get the same error on both boards.

For testing I’m using the BLE_HeartRate app and the HelloBlue app found here https://developer.mbed.org/users/waynek/code/HelloBlue/ and both give the same results. I'm using the Nordic utility on Android 4.4, but to see whether the problem was Android I also tried from iOS8 and I get a similar size limit error.

Do you think the problem is that the boot loader and the SoftDevice get already much space and there is not sufficient space left for the app? Or the problem might be something else?

In case you need any other information let me know.

Thanks a lot in advance for your help.

Walter

19 Jun 2015

Hi,

when using FOTA to update an application on an nRF platform, the bootloader is expecting to receive only the application in a HEX. The soft-device and the bootloader components don't need to be updated.

Building apps using the normal nRF platforms on mbed automatically merges the softdevice HEX into the resulting image. This is designed to generate images meant for USB based transfers through the interface chip on mbed platforms. images (.HEX files) meant for FOTA should not be combined with the softdevice; hence they need to be generated differently. there are shadow FOTA platforms for the nRF51 to allow you to build these lean application-only .HEX files.

Check file sizes of your resulting .HEX. FOTA apps are typically around 20KB - 40KB. Apps combined with Softdevice are around 300KB.

19 Jun 2015

Thanks a lot for your fast reply Rohit. I just compiled the application using the shadow platform and it works. I had overlooked this issue.

The image generated now has indeed a smaller size and it is transferred without problems.

Cheers,

Walter

22 Jun 2015

Hi Rohit,

In my case is a nRF51822 platform, but without an external 32k oscillator.

Could I use the bootloader image(default_bootloader_app_s130_tmp.hex) to execute the FOTA function ? For me, it's an important issue!

If the answer is "NO". Please tell me how to solve this problem.

Thank you for your help!

Harry

22 Jun 2015

Hi, the default bootloader in its current compiled state won't work with a nonstandard platform which doesn't have an oscillator. The bootloader was built after minor modifications using sources from Nordic. You'll find this modified source in a repository under github/armmbed. You'll also find a topic under the community part of mbed.org/ble describing the process if building your own bootloader from sources. You'll find that systemInit (or similar) sets up the oscillator; that's where you'll need to adapt the startup code to perhaps use the internal oscillator.

I'm traveling for a few days, so I'm afraid I can't be of more help. Many others in the community have built the bootloader; so you can expect others to fill in if you ask.

Best,

23 Jun 2015

Hi Rohit,

Thanks for your reply. I'll try it. Enjoy your vacation!

Harry

29 Jun 2015

Hi Harry,

As Rohit pointed out, SystemInit sets up the clock. As you can see in the mbed SDK, the selected clock source depends on the target passed as macro parameters:

mbed_sdk/libraries/mbed/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/system_nrf51.c

#if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
#else
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
#endif

Hopefully, your platform is one of those two. Otherwise, it should be added to the SDK.

In order to build the current DFU bootloader for HRM1017, I needed to add the -DTARGET_HRM1017 flag to add_definitions in CMakeLists.txt

The following change was also needed in main.c:

diff --git a/main.c b/main.c
index 5c20e46..5e10d17 100644
--- a/main.c
+++ b/main.c
@@ -155,7 +155,12 @@ static void ble_stack_init(bool init_softdevice)
     err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START);
     APP_ERROR_CHECK(err_code);
 
+#if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
+    /* Those targets don't use an external source  */
+    SOFTDEVICE_HANDLER_APPSH_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, true);
+#else
     SOFTDEVICE_HANDLER_APPSH_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, true);
+#endif
 
     // Enable BLE stack
     ble_enable_params_t ble_enable_params;

I will soon send a pull request to add this to the repo. In the meantime, I can provide you with an image that should work on an nRF51822 platform without external oscillator: s130_defaultapp_boot_hrm1017.hex

Cheers

02 Jul 2015

Hi,

Thanks for your help! This issue had been solved.

Best, Harry

29 Jul 2015

/media/uploads/Afoster/screenshot_2015-07-29_12.31.41.png

Hi Rohit,

I noticed today that there is now a dropdown beside the selected platform to build App with boot loader and app for FOTA. When I build with default the app works as expected however when I build the app with boot loader my application does not boot.

Is there any documentation around these new options, for example which boot loader is used, the one that you reference above or something different. Have to say it would be useful to be able to build an initial image with soft device + app + boot loader without having to manually create it from the component parts with srec_cat

Thanks,

Allen

29 Jul 2015

Allen,

We'll reply to this shortly. We're making some changes to the build mechanisms around FOTA.

rohit.

05 Aug 2015

Hi, i have downloaded the new initial image. i open computer and i put on j-link (nrf51-dk) the new image, but if i try to update fota with nrfMCP doesn't work. if i put the old initial image on J-link(nrf51-dk) i can update firmware over the air with nrfMCP but the new application doesn't work. I don't understand where is the error. Thank for reply

05 Aug 2015

Hi Enrico,

This may be related to a recent update in MCP or Android, that requires an init packet to be present for some versions of the bootloader... Can you confirm if this is the issue, by looking at the DFU logs? (Slide right on the device window, or select "Show log" in the upper menu)

05 Aug 2015

the log show me: "connection failed (0x85): GATT ERROR, Error 133 (0x85):GATT ERROR Thanks

09 Aug 2015

Unfortunately, that's a generic error, which usually happens when the connection times out because the device is unresponsive. It is not related to the init packet constraint I mentioned previously.

Could you be more specific about which initial images you're using? (new and old)

Can you see the device advertising after the update using the old image? To check this, open the right graph in MCP's device list, and start scanning.

Can you connect successfully to the application when building a Default image? (ie. when skipping the FOTA steps and simply copying a standalone image on your device)

What is your Master Control Panel version? (Right menu -> About -> About application)

20 Aug 2015

Jean-Philippe Brucker wrote:

Hi Harry,

As Rohit pointed out, SystemInit sets up the clock. As you can see in the mbed SDK, the selected clock source depends on the target passed as macro parameters:

mbed_sdk/libraries/mbed/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/system_nrf51.c

#if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
#else
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
#endif

Hopefully, your platform is one of those two. Otherwise, it should be added to the SDK.

In order to build the current DFU bootloader for HRM1017, I needed to add the -DTARGET_HRM1017 flag to add_definitions in CMakeLists.txt

The following change was also needed in main.c:

diff --git a/main.c b/main.c
index 5c20e46..5e10d17 100644
--- a/main.c
+++ b/main.c
@@ -155,7 +155,12 @@ static void ble_stack_init(bool init_softdevice)
     err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START);
     APP_ERROR_CHECK(err_code);
 
+#if defined(TARGET_DELTA_DFCM_NNN40) || defined(TARGET_HRM1017)
+    /* Those targets don't use an external source  */
+    SOFTDEVICE_HANDLER_APPSH_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, true);
+#else
     SOFTDEVICE_HANDLER_APPSH_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, true);
+#endif
 
     // Enable BLE stack
     ble_enable_params_t ble_enable_params;

I will soon send a pull request to add this to the repo. In the meantime, I can provide you with an image that should work on an nRF51822 platform without external oscillator: s130_defaultapp_boot_hrm1017.hex

Cheers

Hi, Jean-Philippe.

I've had a problem with FOTA with nRF51-DK, own board which includes nRF51822 and own board which includes nRF51822

without external oscillator.

I succeeded FOTA with nRF51-DK with rohit's boot loader hex file,

and I succeeded FOTA with own board which includes nRF51822 chip with redbearlab's boot loader hex file.

but I failed with last board which includes nRF51822 without external oscillator.

To FOTA, I think I need 2 hex file. first one is boot load hex file like you upload. Another thing is the hex file which I want to upload

through FOTA and second hex file should be complied "xxx FOTA" platform, such as "nRF51822 FOTA", "nRF51-DK FOTA".

I got "dfuTarg" on nRF master control panel android app by hex file you upload, but I can't upload through FOTA beacause there is

no "HRM 1017 FOAT" platform. How can I do DFU without "HRM 1017 FOTA" platform?

26 Aug 2015

Hi Taeyeop,

It is relatively easy to make an OTA image from a normal one built for nRF51822. Indeed, a default image consists of:

  • The SoftDevice (firmware), from addresses 0 to 0x1800/0x1c000, depending on the version
  • Your application
  • A BOOT image also contains the bootloader at the top. When in "DfuTarg" mode, your device is running from this bootloader, and will only override the application.

"OTA" images only contain your application. You will need a tool to remove the soft device, or a text editor. The following nRF51_OTA_strip.py script does that. It requires python with the intelhex module:

Import programintelhex tools

nRF51_OTA_strip.py: python script that strips an nRF51 image

nRF51_OTA_strip.py app.hex app_OTA.hex

To do it by hand, you'll just need to know where your application start. You are most likely using s130 SoftDevice, so your application will start at address 0x1c000. The following command (installed with intelhex) removes data below that address:

hexmerge.py app.hex:0x1c000: -o app_OTA.hex

You'll also need to do FOTA against a recent BOOT image, if don't use an init packet. Otherwise, the Nordic master control panel will reject your OTA image. If the control panel's logs say that an init packet is required and you're in a hurry, try using a trivial init packet that doesn't contain any CRC: /media/uploads/jbru/ota_empty_init_packet.dat

It is possible to build a BOOT image yourself by merging a normal application, and a bootloader. (Please note that this is the develop branch, not master.)

# With srecord:
$ srec_cat bootloader.hex -intel app.hex -intel -o BOOT_image.hex -obs=16
# Or, with intelhex (You may need to remove one of the start addresses, a line starting with ":04000005"):
$ hexmerge.py bootloader.hex app.hex -o BOOT_image.hex

I don't have a HRM1017 board close at hand to test it, so I don't feel comfortable posting a pre-built image at the moment.

However, the online IDE should soon be able to build BOOT images compatible with all nRF51 targets.

26 Aug 2015

Thank you for replying, Jean-Philippe.

I'm gonna try what you told me.

Thanks,

Taeyeop.

14 Sep 2015

Hi Rohit,

Back in post #9 you provided a default bootloader image based around the s130 ( SDK v8 ) and your dfu bootloader.

The reason I ask is that I was experimenting using this image and some FOTA updates. With the recent changes checked in for the BLE_API ( which I presume are for SDK v9? ) some behaviour such as the UART is now unstable using the SDK v8.0 soft device in default_bootloader_app_s130_tmp.hex. I have traced this back to the softdevice as if I do a complete non-FOTA build ( softdevice + application ) the UART and other BLE services work stably. This obviously makes sense as although an SDK v8 soft device might provide all the library symbols required by an SDK v9.0 BLE_API, the function protos and defines might not necessarily match on both sides causing undefined behaviour.

So I'm going to make my own default image as you suggested using the s130 SDK v9.0 softdevice. In the interim I tried to make use of the FOTA softdevice update in the Nordic tools iOS app. This accepts the softdevice.hex and an softdevice.dat in the same way as application FOTA updates work. However when i tried this update, the FOTA update of the softdevice seemed to complete however the device did not startup correctly afterwards.

So a question, is Softdevice update using the DFU service ( dual bank mode? ) close to being supported? If it isn't it is slightly concerning given the behaviour which I have seen above as it means that on remotely deployed targets, an old softdevice might not be 100% compatible with the current BLE_API. This then complicates source management as I cannot use the latest BLE_API but rather have to use a legacy one which matches my deployed softdevice.

Thanks for your help as always,

Allen

21 Sep 2015

Hi Rohit,

Apologies for bumping this again, do you have an updated bootloader which supports the SDK 9 S130 Softdevice? Or is it a case of simply creating another default image with the sdk 9 softdevice and the current bootloader. When I do this mine does not appear to work correctly. Can you provide one for comparison?

What is the status of the roadmap for mbed FOTA going forward. I know there was some talk months ago about having a build option to include the bootloader so that a default image ( Bootloader + App + Softdevice ) did not have to be created by hand using srec_cat.

Thanks,

Allen.

21 Sep 2015

Hi Allen,

We haven't updated to v9 of the SDK. Could you please share what made you try SDKv9? Are there any significant advantages in doing this? You should be able to rebuild the bootloader.hex using v9 SDK; shouldn't be anything special.

We will be supporting Nordic FOTA for some more time (possibly till the end of the year) before moving to a generic mbed-FOTA.

21 Sep 2015

Hi Rohit,

I thought the current BLE_API checked in Softdevice used the production SDK 9 S130 Softdevice? Which version does it use?

I think the problem is that I didn't rebuild the bootloader with SDK 9. I simply combined my original SDK8 bootloader using srec_cat with the new SDK 9 S130 and an app.

I guess that won't work in hindsight!

Allen

01 Oct 2015

Hi Allen,

Allen Foster wrote:

I thought the current BLE_API checked in Softdevice used the production SDK 9 S130 Softdevice? Which version does it use?

You're right, we're currently using the S130 SoftDevice shipped with SDK8.1 and SDK9, which is version 1.0.0. The one shipped with SDK8 is an older 0.9.0 version, which shouldn't be used anymore.

Note

You can use some tool to inspect FWID in the info struct (at address 0x300c), when you want to make sure of your SoftDevice version:

$ hex2dump.py -r 0x300c:0x300d nRF51_SDK_8.0/components/softdevice/s130/hex/s130_softdevice.hex
5E
$ ... SDK_8.1 ...
67
$ ... SDK_9.0 ...
67
$ hex2dump.py -r 0x300c:0x300d mbed_sdk/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/s130_nrf51822_1_0_0/s130_nrf51_1.0.0_softdevice.hex
67

Allen Foster wrote:

I think the problem is that I didn't rebuild the bootloader with SDK 9. I simply combined my original SDK8 bootloader using srec_cat with the new SDK 9 S130 and an app.

Could you please try combining with the following bootloader s130_nrf51_1.0.0_bootloader.hex ? It was build for the most recent S130.

Update: this bootloader is now available in the live IDE, provided you've upgraded your nRF51822 library to the latest version. To build an initial (default) image, all you have to do is select the "App with bootloader (BOOT)" target in the drop-down menu (see this recent post on the forum).

25 Sep 2015

Hey Guys, I've been having an issue with my program sometimes start up in bootloader mode and advertising as DFUTarg for about a minute or two, before handing over control to the application code, and it seems pretty relevant to this discussion. For simplicity I posted it as a full question here - https://developer.mbed.org/questions/60981/BLE-App-reverting-to-DFUTarg-on-startup/

I'd really appreciate any insights you guys may have on this issue! Thanks, Steve

30 Sep 2015

Hi, I'm trying to figure out the best way to produce a single production ready hex file with OTA bootloader, Soft Device and application, and I read on an earlier post from Jun that there were possible plans to include the bootloader in the normal build. Has there been an update on this?

30 Sep 2015

@Andrew Fox : I was able to get it working using this project as a starting point - https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_HeartRate/?platform=Nordic-nRF51822

Using that along with the nrf51822 device set to "app with bootloader" I get a hex file that contains the S130 1.0.0 SD and a bootloader along with my application.

30 Sep 2015

@Stephen Hibbs Thanks for update