From bug fixes to new features, firmware updates are essential for a device’s evolution. Here’s how to build a reliable update system that keeps your embedded IoT devices running smoothly in the field.
Updating firmware is a critical component in the lifecycle of any embedded IoT device. It provides flexibility during development, but also simplifies support and enables long-term feature evolution. In essence, firmware updates allow these devices to modify their current operational software to fix bugs, improve performance, or introduce new capabilities – like supporting machine learning models that optimize business processes using real-time IoT inputs.
Think of firmware as a program on a computer or a smartphone – except it’s designed specifically to run on embedded systems. Firmware updates can be performed wirelessly when a device is connected via Bluetooth or WiFi. This method is known as an Over-the-Air (OTA) update, or more specifically, Firmware Over-the-Air (FOTA), highlighting its remote and seamless execution.
Problems that firmware updates can solve
Bug fixes
Simple bugs can be addressed through code changes and library upgrades.
Introduction of new features
More complex changes that expand device capabilities.
Security updates
Resolving critical security issues.
Settings changes
Modifying system configurations or default behaviors.
Potential issues with firmware updates
While beneficial, firmware updates can also impose certain risks. If the update contains a bug, or worse, malicious code, it may cause problems with the device:
Inability to update again
Faulty updates may block future installations.
Bricked device
Updates can render a device unusable.
Malicious firmware
Unauthorized updates can compromise device security.
It is crucial to approach firmware updates with caution and ensure proper implementation. Otherwise, a poorly executed update might create more problems than it aims to solve.
How firmware updates work
Enabling firmware updates on a device requires certain memory compromises. The device’s non-volatile memory (Flash memory) should be partitioned into three sections:
1
Current firmware
2
Update firmware
3
Bootloader
The bootloader section can be just large enough to fit the bootloader, while the sections for the current firmware and the update must be equal in size and large enough to store the device firmware.
To partition the Flash memory properly, a linker script should be used to ensure that the linker does not store parts of the code in the bootloader or update the firmware sections. Additionally, the application code should be compiled to execute from the start of the current firmware section to ensure correct jump addresses when running.
Bootloader
A bootloader is essential for enabling firmware updates on the device. Its primary functions include optional firmware verification, installing new firmware, and jumping to the start of the application code. The firmware verification can be done either in the application code before entering the bootloader or within the bootloader itself. When the device boots, it always goes into the bootloader first.
The bootloader then checks if there is new firmware to install: if so, it performs the installation and eventually jumps to the start of the application code. Different methods can be used to notify the bootloader that new firmware is available, such as reading a specific Flash memory address set by the application after downloading the firmware.
Firmware updates involve several key steps:
1
Receiving the firmware
The device receives the new firmware in chunks and saves it in non-volatile memory. This can be done via Bluetooth, WiFi, UART, or CAN. Typically, it is done in the application code to ensure the device remains functional during download, and downtime is kept to a minimum.
2
Verifying the firmware
This step checks if the firmware is valid and authorized, preventing the installation of corrupted or unauthorized firmware that could be malicious.
3
Installing the firmware
The installation process is performed in the bootloader. It involves overriding the current application code with the new firmware, which cannot be done while the application code is running. The bootloader transfers the new firmware from the temporary storage area (update firmware section) to the main operational area (current firmware section) of the Flash memory.
Remote firmware distribution
There are two ways to initiate a firmware update: automatically and manually. The choice of how to start the update depends on the use case and the device’s connectivity capabilities, which can vary significantly in the IoT space.
Automatic firmware updates
With automatic updates, the device takes charge of connecting to the server, checking for new firmware, and initiating the update. Users don’t have direct control over starting the update process.
This approach is suitable for devices with continuous or intermittent connectivity or those with unstable connections. All that’s needed is to release the firmware update on the server. The device can be configured to start the update based on certain conditions, such as a specific time of day or reaching a particular state.
Manual firmware updates
For a manual update, the user must trigger the firmware update process – highlighting the importance of designing clear, user-friendly interactions in IoT interfaces. This can be done in various ways. It could be initiated by the device itself, using some form of user input available. Alternatively, another device could be used to start the update, or an external device might be employed to initiate the process. This type of update works for all types of devices, regardless of their connectivity, ranging from always connected to never connected.
Manual updates require user intervention to start the firmware update process. There are several ways to initiate this process:
- Directly on the device itself, using the input methods available
- Through another connected device
- Via external hardware
The advantage of manual updates is their versatility – they work with all types of devices regardless of connectivity status, from always-online devices to those with no regular network connection.
Updating non-connected devices
Devices that are only connected on demand can be updated through Bluetooth connectivity solely for firmware updates. In this scenario, the device advertises itself and waits for a connection. The user can connect the device to a smartphone via Bluetooth, download the firmware update file to the smartphone, and then transfer it to the device to start the update.
Non-connected devices can also be updated manually using wired protocols like UART or CAN, or external storage devices like an SD card. The device can have a specific user input that triggers the firmware reception from the UART, SD card, or other wired protocol. If using UART, CAN, or any other wired protocol, there must be an external device to communicate with the main device being updated and to contain the firmware file.
Security measures in firmware updates
Security is enforced primarily during the firmware validation step. The main goal is to ensure the received firmware is legitimate and free from tampering. Several essential steps fall under this category, including integrity checks, firmware decryption, and firmware signing checks. Some of these operations may involve asymmetric encryption, with the keys needing to be securely stored in encrypted Flash memory or protected against unauthorized access.
When both firmware encryption and firmware signing are in place, the following keys are typically found on the device:
Device private key
This key is known only to the device manufacturer and is used for firmware encryption.
Manufacturer public key
This key is employed for firmware signing and is made public by the manufacturer.
Integrity check
The integrity check step ensures that the received firmware is error-free during communication, detecting potential issues like bit-flips. The device calculates the hash of the received firmware using methods like md5, and compares it with the hash received along with the firmware. A match indicates that the received firmware is intact and uncorrupted, allowing the device to proceed to the next validation step. This step is crucial for preventing the installation of corrupted firmware that might lead to unexpected behavior.
Firmware decryption
Firmware encryption is the process of encoding the firmware information to prevent unauthorized access to its content. When encrypting the firmware, the device’s public key is utilized. Upon receiving the firmware, the device uses its private key to decrypt the firmware for further processing.
Firmware signing check
Firmware signing involves encrypting the firmware with the manufacturer’s private key, which confirms that the firmware comes from the manufacturer. However, it is not practical to encrypt the entire firmware with the private key. Instead, only the firmware hash is encrypted, and cryptographic hash functions like SHA-256 are commonly employed for this purpose. This way, the device can validate the authenticity of the firmware by decrypting the hash using the manufacturer’s public key.
The importance of updating firmware
As technology advances, digital services constantly evolve. With the continuous introduction of new products featuring the latest technologies and improved features, you can enhance your existing devices by simply updating their firmware, enabling your older hardware to keep up with the latest capabilities.
This article is adapted from our Guide to Successful IoT Implementation, where we cover the technical foundations and strategic considerations behind building modern IoT solutions. For more insights, download the full guide.