Almost all embedded systems require the ability to update their firmware in the field to add new features or fix bugs. However, field firmware updates can be quite challenging because developers must either write their own bootloader or purchase one from a third-party component vendor.
There is a relatively simple method. This article will introduce how to use the Device Firmware Update (DFU) feature, which is built into many microcontrollers but is often overlooked.
Firmware update options
Developing a bootloader from scratch is no easy task. Developers need to resolve their flash memory space so that multiple applications can coexist. Then, they also need to develop several methods to transfer their compiled binaries to the microcontroller without using programming tools. This requires them to develop their own communication protocols or add external memory to store new images, increasing the complexity of the system. They also need to increase the memory capacity on their microcontroller.
Similarly, the software itself becomes more complex because the bootloader needs to set up the system state and determine whether it is safe to jump to the application code.
Using a custom bootloader can provide developers with the flexibility their applications desperately need, but many applications that require minimal developer effort can utilize a firmware update standard: the USB standard's Built-in Device Firmware Update (DFU) class. This allows for field updates of the microcontroller's application code via its USB port, significantly reducing the firmware upgrade process and development cycle.
DFU (Distributed Functions Activated) is so widely used that some microcontroller vendors, such as STMicroelectronics, even provide the software needed to perform updates hard-coded into their ROM. Those that don't usually provide sample code demonstrating how to support DFU.
Choose a microcontroller suitable for DFU.
The simplest way to support DFU is to choose a microcontroller that already has DFU included in its ROM, such as the devices on STMicroelectronics' STM32 IoT Discovery Node and STM32F429 Discovery Kit.
Figure 1: The STMicroelectronics STM32 IoT Discovery node is based on an ARM® Cortex®-M4 core running an STM32L475 MCU, which includes DFU mode functionality for firmware updates. This particular device is designed for use as an IoT node.
The STM32IoTDiscovery Node is a low-cost development board designed for use as an IoT sensor node. The board includes several different interfaces for connecting to boards with Wi-Fi and Bluetooth connectivity. Of particular interest is the onboard STM32L475, which provides developers with the ability to test and use DFU functionality on devices designed for internet connectivity.
For developers who simply want to test DFU on standalone, normal devices, the STM32F429Discovery kit is a well-known, low-cost development kit for the STM32F4 series microcontrollers. We'll discuss how developers can get started testing DFU on these microcontrollers.
Figure 2: The STMicroelectronics STM32F429 Discovery kit is based on the ARM® Cortex®-M4 core. This low-cost development board's MCU also includes a DFU mode function for firmware updates.
A simple DFU example
Each microcontroller accesses DFU in a different way. Let's look at a simple example of how developers can update the firmware on a device running an STM32L475 MCU.
As mentioned earlier, the STM32 microcontroller includes a DFU bootloader built into its ROM. To access this bootloader, developers need to ground one of the BOOT pins when the MCU starts up. The BOOT pin controls the mode in which the MCU starts, such as booting from flash memory, RAM, or our preferred DFUUSB mode.
Preparing an application for download using DFU requires no additional work from the developer. The GNU Compiler Collection (GCC) and many other toolchains support generating DFU files when compiling the application. The only trick for developers here is to determine the storage location of the file: as with all typical applications, to find the .dfu file, refer to the debug or object folder.
DFU files are very similar to other application record formats such as binary, s-record, and hexadecimal files. The file format includes address and data information that is forwarded via USB relay, processed, and then written to a specified location in flash memory. This process is seamless, requiring developers to rarely (if any) inspect the protocols being used. All of this happens in the background, helping to reduce the complexity of firmware update processes and development efforts.
Developers can use several different tools to migrate their applications to microcontrollers via DFU. dfu-util is a general-purpose command-line tool that can be used. It is available as an open-source package on both Linux and Windows®. If developers use the STM toolchain, they can leverage STMicroelectronics Applications DfuSe (Figure 3).
Figure 3: STMicroelectronics DfuSe tool can be used to program DFU files generated by compilers such as GCC and loaded into microcontrollers suitable for DFU.
DfuSe is a Windows GUI utility that detects any STM32 device powered on in DFU mode and connected to a computer via USB. Developers can retrieve information such as programming vendor and product ID. Without proper security measures for the flash memory, they can even copy the MCU's stored contents and save them to the computer using the upload operation box.
When using DfuSe, developers typically only use the "Upgrade" or "Verify Operation" sections. In this area, developers can select their DFU application file and then choose the Upgrade button. DfuSe will then automatically coordinate the firmware update process until the entire file has been successfully loaded into the MCU. Developers can then choose to verify that the image has been successfully received. Once verified, the BOOT pin can be set back to its default configuration, such as booting to flash memory, and then the 'Exit DFU' mode can be selected to load and execute the updated firmware.
Using DFU on a device without DFU support
The fact that the microcontroller does not provide a DFU bootloader in ROM does not mean that developers cannot utilize DFU functionality. DFU belongs to the USB class and is supported in many USB stacks. This means that developers can still easily add DFU functionality to their application frameworks and still perform DFU updates.
For example, Microchip Technology's AT32UC3A3 does not have a built-in DFU mode (Figure 4). Developers can follow the simple application instructions that describe how DFU works and how they should configure their microcontrollers to properly support DFU.
Figure 4: The AT32UC3A3UC3-A3XPLDAVR® 32MCU 32-bit AVR embedded evaluation board does not include on-chip DFU, but a frame USB code supporting DFU firmware update features can be added.
Tips and tricks for performing firmware updates
On-site firmware updates are not necessarily limited to microcontrollers suitable for DFU (Dual Functions Update). Developers can decide whether alternative methods for updating firmware are necessary or more practical. In this context, developers should keep several tips in mind regarding their firmware update process. These include:
Applications that use checksums or hash verification to write to the microcontroller's memory.
Choose a microcontroller with sufficient memory to store a backup of the firmware so that the firmware version can be rolled back in case of errors.
The verification confirmed that when the microcontroller has a built-in flash loader, the end user will not accidentally trigger the program.
Ensure that any software bootloader is compiled and optimized for size.
Locking flash peripherals prevents applications from reading them from memory and from being reverse engineered.
Make sure that the stack pointer, vector table, and program counter register are all set to the appropriate application values.
Consider using an alternative update method, such as drag-and-drop update via USBMSD, as demonstrated in the KL46ZFreedom board demonstration (Figure 5).
Figure 5: NXP Semiconductor's KL46Z Freedom board is a low-cost development board that does not support DFU by default. Developers can use alternative update methods such as USB MSD to drag and drop new firmware images into memory.
Summarize
Almost all embedded systems require on-site updates to application code to avoid callbacks. Creating a bootstrap from scratch or modifying an existing bootstrap can increase the complexity of the development cycle and integration issues.
Conversely, developers can use the well-proven DFU functionality built into the USB standard to perform field upgrades quickly, efficiently, and effortlessly. For this process to proceed smoothly, developers need to carefully examine their microcontrollers and determine whether DFU is built into them or whether they require a software stack that supports DFU functionality.