Based on the documentation of BLE Secure DFU example, it supports on the BLE / ANT/Serial UART DFU.
This blog would mainly focus on the Serial (UART) DFU. Inside the Nordic official example, it would use the nrfutil (written in Python script) as the host application for device firmware upgrade.
I would use another alternative host application (in C code, based on nRFutil 3.5 version) to show how to do the application FW upgrade only. This example is tested at the SDK 15.2 under Window or Linux Ubuntu environment.
nrfutil is a Python package that includes the
nrfutil command line utility and the
Here are the procedure how to run on the serial DFU on NRF SDK.
Download the Nordic NRF5 15.2 SDK (http://developer.nordicsemi.com/nRF5_SDK/)
Prepare the GCC compiler Install the GNU ARM Embedded compiler / Linkerhttps://developer.arm.com/open-source/gnu-toolchain/gnu-rm
For example, this compiler is installed at C:\Tools\gcc-arm-none-eabi-7-2018-q2-update-win32
Modify the corresponding makefile inside the Nordic SDK (e.g. window — nRF5_SDK_15.2.0_9412b96\components\toolchain\gcc\Makefile.windows)
Download / Compile the micro-ecc library (because secure DFU requires to use the micro-ecc 3rd party library)
- Install the Chocolatey (Software Management Automation)
- Install the make package under chocolatey tool (run the command prompt terminal as administrator right)
- Install the git at the terminal (recommended to use cmder terminal or download from choco install git)
- Run the batch file (build_all.bat) under nRF5_SDK_15.2.0_9412b96\external\micro-ecc folder
Generate the private key and public key (Make sure the version of nRFUtil is 3.5 if you are using the SDK 15.2 DFU, nrfutil version)
You can download the pre-compiled execute file at https://github.com/NordicSemiconductor/pc-nrfutil/releases. nRFUtil works on the Python 2.7.x currently.
@echo generate the private key
nrfutil keys generate demo_private.key
@echo generate the public_key from private key
nrfutil keys display --key pk --format code demo_private.key --out_file demo_public_key.c
Update the public key at the bootloader project (dfu_public_key.c)
Recompile the bootloader (secure_bootloader\pca10040_uart_debug in this case) on the SES project file.
Prepare two difference application firmware files and generate corresponding zip package for testing by using the private key.
nrfutil pkg generate --hw-version 52 --application-version 1 --application ble_app_uart_pca10040_s132_FW1.hex --sd-req 0xB7 --key-file demo_private.key app_uart_fw1.zip
nrfutil pkg generate --hw-version 52 --application-version 1 --application ble_app_uart_pca10040_s132_FW2.hex --sd-req 0xB7 --key-file demo_private.key app_uart_fw2.zip
The softdevice version (sd-req) can be found at nrfutil github (https://github.com/NordicSemiconductor/pc-nrfutil).
In this case, S132v6.1.1 (version 0xB7) is used. You can check the softdevice version athttps://github.com/NordicSemiconductor/pc-nrfutil.
Thanks for your interests on my blog. Since 2019, I have created this blog and shared the idea how to do some funny stuffs. I am very pleasure that I get quite a lot of positive feedback. I really hope that this blog helps your own embedded solution development. May I get support from you to keep it in order to maintain the wordpress host service? Your appreciation would be very helpful.
Greate pieces. Keep posting such kind of info on your
blog. Im really impressed by your blog.
Hello there, You have done a great job. I will certainly digg
it and individually suggest to my friends. I am sure they will be benefited from this site.
You need to be a part of a contest for one of the most useful websites on the web.
I am going to recommend this website!
I can’t compile your C Code, can point me on the right direction?
You just need to use the make file either under windows (such as MSYS2) or linux.
if you use the windows, you need to specify the makefile such as you need to add the make -f Makefile_win32 (makefile for window platform).
Its mentioned as “application FW upgrade only”. So with C code, whether only Application can be upgraded. Any plans for SoftDevice and Bootloader up-gradation feature ?
It can support softdevice and bootloader upgrade. This blog is to share the demo what I did. Please notice that it is not bug free guarantee.
I used this code for nRF52840 Softdevice,Bootloader,App from raspberry pi over UART and it is working fine. but when either Softdevice/Bootloader merged firmware or App firmware update is running, and it is stopped , it is unable to resume firmware update process.
The UART DFU is only tested on the SDK 15.2 (with nRFUtil 3.5). You may need to check at your configuration.
The code is just to share the proof of concept. It doesn’t guarantee to work on all the conditions. Please notice about this.
I have a query on Secure Serial DFU, whenever there is a change in Flash and Ram address.
In original example code below are the macros.
After adding our code, we need to modify macro to
Because of this will it cause any issue if we do Secure Serial DFU on original binary with latest package with changed FLASH_SIZE and RAM_SIZE macros.
I think It should work fine on your modification.
This application is exactly what I was looking for but I am trying to get it to work over serial USB (not UART) to the nrf52840 dev kit. It seems like it ‘should’ work but am running into troubles with the UART_SLIP_SIZE_MAX of 128 being violated and causing failure in uart_slip_send():
if (nSize > UART_SLIP_SIZE_MAX)
logger_error(“Cannot encode SLIP!”);
err_code = 1;
I increased UART_SLIP_SIZE_MAX and things progress further (the init packet gets sent) but sending the image fails. Do you know if this should work over serial USB and if not what changes might be necessary?
I think you can configure the LENGTH to 64 for trying. As I remember , it should work on the USB bootloader also.
I changed UART_SLIP_SIZE_MAX to 64 like you suggested. Still not working. Here’s a trace from running the app (note that I added extra logging of the length of the message sent over slip shown as uart_slip_send: nSize = NN). You can see that it fails when trying to send a message of 1025 bytes since UART_SLIP_SIZE_MAX is set to 64).
Sending Application image.
uart_slip_send: nSize = 2
Set Packet Receipt Notification 0
uart_slip_send: nSize = 3
uart_slip_send: nSize = 1
Sending init packet…
SEND INIT PKT 1
Selecting Object: type:1
uart_slip_send: nSize = 2
Object selected: max_size:512 offset:141 crc:0x55771FB9
SEND INIT PKT 2
uart_slip_send: nSize = 1
Sending firmware file…
Selecting Object: type:2
uart_slip_send: nSize = 2
Object selected: max_size:4096 offset:0 crc:0x00000000
uart_slip_send: nSize = 6
Streaming Data: len:4096 offset:0 crc:0x00000000
uart_slip_send: nSize = 1025
Cannot encode SLIP!
FYI – I found that your DFU app works with the nrf usb serial bootloader if UART_SLIP_SIZE_MAX is set to 2048.
Yes, I tried it before.
Hi Jimmy, thanks for your sharing. But I find that I can only do UartSecureDFU.exe COM8 app_uart_FW1.zip -v -v once and it succeed. Later if I want to upgrade to another FW e.g. I type UartSecureDFU.exe COM8 app_uart_FW2.zip -v -v and it tells me “Read no data from UART!”. No matter how many times I try always the same. How can this be fixed?
So the Host can only upgrade firmware when there’s no application code inside? And can only upgrade once? Now if I want to change to another app firmware, I need to remove the app firmware inside and then type UartSecureDFU.exe COM8 app_name.zip -v -v.
Anything I did wrong? Do I misunderstood some of your instruction? Thank you in advance.
I think it may be related to the version (application). You may check on the bootloader setting why it doesn’t work on the 2nd time.
Hi Jimmy, thanks for your sharing.I want to move this code to the microcontroller, is it feasible?
Yes, you should do it on the microcontroller instead of the windows host.
However, can you open and read zip files on the MCU？
You should modify the code to use such as binary input file instead of zip format.
Do you have sample code for this？
I post this host tool just for your reference. if you have any special feature, you can modify it by using the binary file format. It is very straightforward.
You can also refer to the another blog on this example (https://blog.classycode.com/updating-the-firmware-on-an-nrf52-from-another-microcontroller-b513080dc0cd)
Thank you, I have another question, can the version after SDK16.0 not use secure DFU, I want to only transfer app bin file, but not the key file.
We can discuss through my contact (email) for further discussion.
Hi Jimmy – we ported this to various platforms and have it working with USB. For the most part it works great! One issue – if we interrupt the update half way through (for example by pulling power on the target), the serial DFU will not recover when trying the update again (it times out connecting to the bootloader). However nrfutil seems to be able to receiver from this. We’re using dual bank update.