At ESC Boston this week, I have the privilege of presenting a half-day tutorial on “Bootloader Design Techniques for Microcontrollers.” Bootloaders, sometimes referred to as flashloaders, are a separate application (not a products application code) that resides in microcontroller memory that is used to assist developers in updating their software without having to open their device and get access to JTAG or other debugging ports. Bootloaders have been around in embedded systems for decades but throughout my world travels and interactions with engineers, I’ve found that many teams overlook their importance and don’t fully understand how to go about creating a robust one. Even worse, details about how to go about creating a bootloader are scattered throughout the web without any one source providing developers with all the information they need to successfully create their own. In this post, I’ll discuss the different options product teams have for creating a bootloader for their system and provide some resources that will dive into the details on how to create your own bootloader.
There are several options that developers can use to create their own bootloader. First, many microcontrollers come with an internal, factory bootloader. The factory bootloader exists in the microcontroller ROM and can be accessed by developers to flash their application image onto the microcontroller during the product manufacturing process. If a developer doesn’t require a robust solution, error handling or security, these factory bootloaders may be just smart enough to use out-of-the-box. Device Firmware Update (DFU) has become a popular method for updating firmware over USB that is built into the microcontroller. In order to use dfu, a developer must:
- download the DFU utility, such as dfu-util or DfuSe from ST Micro
- compile their code into a .dfu image file
- hold down a specific GPIO pin during microcontroller boot
- us the dfu utility to then update their firmware
The dfu option works great for rapid prototyping but in a production environment, having to have a specific GPIO that needs to be pulled to a specific state can be dangerous. What happens if a user accidentally triggers the right state and restarts? Suddenly their system doesn’t work and they have no clue why.
A second option that developers can use to create a bootloader for their system is to use a bootloader that is provided by their microcontroller vendor. Using a vendor-supplied bootloader can make a lot of sense since the skills necessary to create a bootloader require an expert understanding of what’s happening in the microcontroller. A bootloader developer needs to understand the:
- Linker file
- How to co-locate multiple application images
- Detect a new image
- Validate new application images (Checksums, CRC’s, Security issues)
- Write to flash
- Recover if an update is aborted or power fails
- Branch to a new application from an application that is already running
- How to debug multiple applications in memory
- Etc., etc., etc.
There is quite a bit to it and the list was only getting started. Using a vendor-supplied bootloader can help a developer quickly get over a learning curve hurdle. The bootloader can even act as a starting point for developers to take and then build on for their own solution. In many cases, the vendor-supplied solution is a great example that is functional but nearly always lacks proper error handling, robustness, and security.
Another option that developers have available to add a bootloader to their system is to use a third-party supplier to create one for them. Outsourcing bootloader development can make a lot of sense because it allows a team to focus on their product features and not firmware updates which can be a complex topic all on its own. As a consultant who has developed a few dozen bootloaders, I won’t go any further into the details on this option.
The final option is to create your own bootloader. Diving into the details can be quite rewarding and challenging. Bootloaders reveal just how well, or not well, a developer understands their microcontroller, embedded software and how to debug applications. A typical development effort for an experienced developer can take four to six weeks depending on the complexity and interface requirements. A developer with little to no experience with a bootloader can easily take 10 to 12 weeks. The learning curve and bugs are not trivial.
So how does a developer interested in bootloaders learn how to write their own? There are several resources that a developer can use to get up to speed such as:
- Attending my Bootloader Design Techniques tutorial (I know a little bit of self-advertising but at least it’s obvious).
- Downloading several microcontroller vendor application notes on bootloader applications and experimenting.
- Reading articles and white papers on the topic and once again experimenting by trial and error ( here is one I wrote).
- Attending my Design News CEC course on bootloaders.
No matter which option you decide to use to implement a bootloader, don’t treat it as a trivial system component. Improper bootloader implementation can result in a bricked embedded system, a security vulnerability or a maintenance nightmare. A bootloader should be developed early in the design cycle rather than added as a last minute final touch to the system. The more time developers can use and test the bootloader and firmware update and management system, the fewer headaches they will have making sure that they can successfully update their firmware.
Bootloader Design Techniques for Microcontrollers.
Remotely updating firmware is critical for any embedded system and even more so for an IoT device. Bootloaders are often added along side application code to facilitate firmware updates but very few developers truly understand how to build one robustly. Join Jacob Beningo as he examines the fundamental challenges facing software engineers in performing updates in a secure and safe manner during his half-day tutorial, "Bootloader Design Techniques for Microcontrollers" at ESC Boston 2017 , May 3-4. Register today!
Jacob Beningo is an embedded software consultant who currently works with clients in more than a dozen countries to dramatically transform their businesses by improving product quality, cost and time to market. He has published more than 200 articles on embedded software development techniques, is a sought-after speaker and technical trainer and holds three degrees which include a Masters of Engineering from the University of Michigan. Feel free to contact him at [email protected], at his website www.beningo.com/, and sign-up for his monthly Embedded Bytes Newsletter.