Introduction
DFU or Device Firmware Update refers to the capability to replace the current firmware running on nRF52 SoC by a new firmware image. In this article, I will explain what you need to add DFU capability to your nRF52 projects.
Why do you need DFU on nRF52?
Before we discuss how to add DFU capability to your nRF52 applications, let’s answer the question why you might want DFU functionality?
Typically, when you develop firmware for your products, you will have a programmer or debugger that has physical access to SWD or JTAG interface of the nRF52. It allows you to flash and read back your code and do all sort of debugging that are necessary. If you make a mistake in your code, just erase everything on the chip’s flash memory and re-program it again.
When your products have been sold to customers, however, you won’t have physical access to the chip anymore to reprogram it. What would you do if you found a critical bug in the firmware that needs to be fixed, or you want to add a new feature to your products by upgrading the firmware? This is where DFU functionality becomes handy. If your products have DFU capability, you can apply bug fixes and add new features to them even after you have sold them to customers. It also allows you to speed up your development phase and pushes your products to market earlier.
What components are required to do DFU?
Now you understand that DFU might be a good option for your product. The next question is what are required to support DFU?
- First, you need a new firmware image and somewhere to store that firmware and customers can access it. For example, it could be stored in your server on the cloud.
- Second, you need a host machine that can communicate with the nRF52 SoC inside your product, so that it can deliver the new firmware image to the chip. The host machine could be a computer that communicates with the nRF52 via an USB cable. It could also be a smartphone app that talks with nRF52 via bluetooth low energy link.
- Third, your nRF52 SoC needs to have the capability to receive the new firmware image, validate it and replace the old firmware in its flash. This is accomplished by adding a program called bootloader with DFU capability to the chip.
The three components are illustrated in the below diagram
nRF52 Secure DFU vs Open DFU
Secure DFU means the nRF52 is able to verify that the firmware image is from a trusted source. Open DFU means the nRF52 does not check the origin of the firmware image (potentially malicious) and will replace the old firmware with everything it receives. You should only use open DFU during development.
So, how does secure DFU work? How can the nRF52 chip checks if the new firmware image is legitimate? The way it works is by using cryptographic keys. The nRF52 knows a public key and uses it to decrypt the signature of the image sent by the host. Before sending the new firmware to nRF52, you need to encrypt the signature of the image with a private key that only you know. After receiving the image, nRF52 will calculate the hash of all data it receives, and if it matches with the expected hash, then the image can be trusted.
What is the role of bootloader
Now you know that the nRF52 needs to receive the new firmware image, validate it and replace the old firmware. A small program called bootloader is responsible for all these tasks. So, when we say adding DFU functionality, what we really mean is to develop a bootloader that supports DFU. The bootloader will run before your main application and check if there is an application needs to be activated. If yes, it will replace the current application by the new one. Otherwise, it will boot up your application.
Memory layout when a bootloader is used
When working with DFU bootloader, it is very important to understand where different parts of your programs are located in internal flash memory. The table below lists different regions for nRF52832 with 512 kB of internal flash:
Bootloader settings --- 0x0007F000 - 0x00080000 (4 kB)
MBR parameter storage --- 0x0007E000 - 0x0007F000 (4 kB)
Bootloader --- 0x00078000 - 0x0007E000 (24 kB)
Application area --- 0x00026000 - 0x00078000 (328 kB)
SoftDevice --- 0x00001000 - 0x00026000 (148 kB)
Master Boot Record --- 0x00000000 - 0x00001000 (4 kB)
As you can see, the master boot record (MBR) stays at the bottom of the flash, followed by the softdevice. If your application does not contain softdevice, the application can start right after the MBR. The bootloader (from secure_bootloader examples in nRF5 SDK) occupies 24 kB, starting from address 0x78000. If you are building a custom bootloader, you will need to adjust this start address and region size appropriately. The bootloader settings and MBR parameter storage are both 4 kB each and stay at the top of the flash address.
Bootloader settings
The bootloader settings is a page at the top of the flash and contains information about bootloader and DFU information. The bootloader settings are loaded from flash memory to RAM and are checked when device boots up to see whether a pending firmware activation exists. If not, it checks whether a valid application exists. During DFU process, it keeps information about current update progress. It also stores information about current firmware version so that it can check against the init packet.
DFU protocol
The DFU protocol is a communication protocol between the host and the nRF52. The host issues a command with optional data, and the nRF52 responses. For example, the host can issue a command asking the nRF52 to erase a page in its internal flash memory to reserve place for new firmware data. The whole firmware image is divided into objects of 4 kB and transferred through different DFU transport medium (e.g. UART, ble). Upon receiving an object, the nRF52 writes it to a location in its internal flash memory. The place where to write it will depend on whether the update is single bank or dual bank.
Before sending actual firmware image, the host will send an initial packet to the nRF52 containing information about the incoming firmware image, such as size, version number etc. The nRF52 will check these information before deciding whether to accept a new firmware image.
Dual bank and single bank firmware update
When updating firmware, the first step is nRF52 to receive the new firmware image and store it somewhere in its internal flash memory. Due to size limitation of the flash, for example, nRF52832 only has maximum of 512 kB of flash, in some cases, you need to erase existing application on the chip so that there are free space to accept new image. If you erase the application, that means it is no longer available and when an unexpected error happens, there is no valid application in the memory anymore. The device will reboot and stuck in the DFU mode. This is called single bank update.
If the size of the application is small enough to fit in the free space in flash memory, in this case, there is no need to delete existing application. The device will save the new image in the free area. In case of unexpected error and the device reboots, it will boot up the old application. This is called dual bank update as two banks are used. Bank 0 contains the old application. Bank 1 contains the new application. After receiving the new application in bank 1, the device reboots and activates the new image by copying it from bank 1 to bank 0 address, then update bootloader settings to mark DFU completes.
What tools do you need to develop nRF52 DFU?
Now you decided your products need DFU capability. Where do you start and what tools are required? In this section, we will look at different tools that you need:
- Hardware: you need a development kit to get started and experimenting with nRF52 DFU. We will be using PCA10040 board for our example projects.
- Software: The following software packages are required
- nRF5 SDK version 17.1. The best place to get started with DFU project is to look at examples folder in the SDK. For DFU, look at the examples at
nRF5_SDK_17.1.0_ddde560/examples/dfu
folder which contains both open and secure bootloaders. - gcc-arm-none-eabi-9-2020-q2-update. Since we are using GCC for our development, you need to download GCC ARM Embedded Toolchain. You can learn more about using GCC for developing nRF52 application in our previous article here.
- nRF Command Line Tools: This contains
nrfjprog
to flash the program to the target chip. nrfutil
: this is a utility provided by Nordic which allows you to:- Generate public and private keys which are required if using secure DFU.
- Generate firmware image in .zip format to send to nRF52 SoC.
- Send the firmware image from a PC to nRF52 using USB/UART interface.
nRFConnect mobile app
: This is a mobile app on iOS/Android that allows you to do DFU via bluetooth low energy.
- nRF5 SDK version 17.1. The best place to get started with DFU project is to look at examples folder in the SDK. For DFU, look at the examples at
Wrapping Up
In this article, I have explained the high level concepts of doing device firmware update for Nordic nRF52. Some of the presented concepts might sound unfamilar with you, they will come clearer once you practice building some bootloaders. If you want to learn more about DFU and bootloader, you can visit Nordic Infocenter, however, it may not be the best place for beginners. In the coming articles, I will show you how to build and test nRF52 DFU functionality over serial link and over bluetooth energy. See you in the next article and thanks for reading.