Mastering the Embedded Update Process
The importance of updating your product after it’s in the field cannot be overstated. Not only is it essential for customer satisfaction with feature updates and bug fixes, but also for addressing security vulnerabilities. In this post, we’ll look at some key considerations and methodologies for updating embedded systems.
Selecting an update approach
Choosing the right method to update your embedded system is the initial challenge. Let’s explore four widely considered approaches.
- Package updates – Using package management tools like apt or yum to download and install updates might appear attractive for their reliability and cost-efficiency. However, this approach comes with several drawbacks such as fragmented updates leading to inconsistencies across devices, challenges in updating system-level components, complex rollback procedures, and difficulties in targeting specific customer segments.
- Containers – Containers broaden the scope of update capabilities and can increase reliability and testability. However, they share some limitations with package updates, including complexities in managing system permutations and limitations in updating low-level parts of running systems. Containers are more suited to environments where OS stability is not affected by updates or when the OS comes from a board vendor. Yet, they are not a one-size-fits-all solution for all update scenarios.
- Full firmware image – We advocate for deploying complete bootable firmware images for updates, particularly in systems under your full control. This approach allows for comprehensive system testing and updates to low-level components. It also streamlines version management and is compatible with an A/B update scheme, allowing for fail-safe updates through dual bootable partitions.
- Hybrid strategy – For those looking to combine the thoroughness of full system updates with the agility of container-based approaches, a hybrid strategy might be your best bet. This introduces the flexibility of container updates to A/B systems, offering agile application updates with minimal disruption. However, it also increases complexity and developer overhead by necessitating two separate update mechanisms.
Given the substantial size of full firmware updates, using some sort of compression algorithm is necessary to conserve bandwidth and reduce download times. Using delta updates to further minimize payload sizes is another consideration, although this adds complexity in version management and may only be available in commercial products.
Partitioning the system
When partitioning an updatable embedded system, we recommend using an A/B partition scheme for firmware – one for booting into and the other for receiving a new download – complemented by an additional data partition and, in some circumstances, a rescue partition. This configuration provides a robust framework for updates. Although it doubles flash storage needs, it allows for background downloads and full validation of new images before executing them, significantly enhancing system reliability.
Running reliably
A critical step in the update process is to switch to a new bootable partition only after a newly downloaded image has been thoroughly validated against a verifiable hash or checksum. If validation fails, the system reverts to the existing verified image.
It’s also important to include a fail-safe so that if the newer code fails to boot, a hardware watchdog can reset the system. The boot loader needs to be smart about how it sets the A/B partition selector so that a watchdog reset reverts things back to a stable state if the new image can’t boot.
Rescue partition
A rescue partition is a dedicated partition that will erase the system and any customer or configuration data and then download a fresh new image. It’s worth considering for data privacy or as a failsafe against the device being bricked. It’s a last-ditch effort so its inclusion should be based on dedicated and reliable initiation methods, such as a hardware button or DIP switch.
Managing your data
How do you ideally manage data in an A/B configuration? Keep it in a dedicated partition separated from executable code. This simplifies updates and ensures user-data retention regardless of system updates.
It’s also essential to maintain both forward and backward compatibility in data structures to ensure both seamless updates and roll-back capabilities. Employing adaptable coding practices and evolvable data formats are key to avoiding interoperability issues between versions.
Concluding thoughts
There is a lot to consider in the realm of embedded system updates and this post just scratches the surface. For a more complete look into managing the complexities of an embedded product software update strategy, please visit our best practice guide, Updates Outside the App Store.
If you like this article and want to read similar material, consider subscribing via our RSS feed.
Subscribe to KDAB TV for similar informative short video content.
KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.