*Updated Sept 2021* Bootloader and firmware update system now available as part of STM32 Secure Patching Bootloader on GitHub.
*Updated Dec 2020* Demo now features using an embedded USB host in the bootloader to update the main application with a USB flash drive.
Every IoT and embedded system needs a way to update firmware in the field. For all but the simplest of projects, features are added, fixes are made, and pushing out updates has become the norm in every software project, and firmware is no exception.
This project describes and demonstrates a complete firmware update solution for STM32 MCUs offering an industry-leading feature set including:
- Encryption
- Authentication
- Delta Patching
- Dual Image
- Image Hosting on External (Q)SPI Flash
- Build Tools and IDE Integration
- Integrated USB Host for updating with USB Flash Drive
This solution is designed to support updating the most advanced firmware applications - like those incorporating UIs like TouchGFX - in the field. A new feature we call Multi-Segment enables seamless booting, updating and patching of firmware applications using TouchGFX that are spread onto memory mapped external SPI flash - treating the combination of internal and external flash as one logical active region.
With this new capability it is now possible to patch a single GUI asset - say a 32 KB icon - in an 8 MB GUI application system - on an STM32 MCU. This firmware update system can do that without any constraints on your application.
A lot of STM32 MCUs include USB OTG cores with Host capability (think L4, F4 and others), so the FM-SBSFU combined with this user-friendly update method has wide applicability to embedded devices featuring MCUs across the STM32 family.
In addition, there are modules available for downloading the patches OTA with just about any method including:
- Cellular (HTTP/FTP - suitable for a variety of systems)
- LoRaWAN (for small IoT projects, patching is a must)
- USB Flash Drive (featured in this new updated demo - good choice for end users)
- Contactless NFC (great for mobile devices - hooray no Bluetooth required!)
- YMODEM over UART (featured in previous demo, more technical)
- Custom (Ethernet, etc)
The patching and programming files are automatically generated at the end of each build with post-build shell and python scripts. We've deployed this to STM32CubeIDE.
If this is interesting for you, read on. We'll get into the nitty gritty of how this works. Let's start with a demo.
TouchGFX Firmware Update DemoThis demo works on the STM32F769I-DISCO and will go through the process of patch updating the application. The demo will change the middle image from that of "colorful balls" to that of a scuba diver.
To run the demo you'll need an STM32F769I-DISCO board, a USB flash drive, the STM32CubeProgrammer, the two demo files: a main .hex programming file and the .sfbp update patch file, located in the attachments ("Schematics") section at the end of this project:
- SBSFU_MultiSegPatchDemo-USBFlash_STM32F7DISCO_v1.0.0.hex
- MultiSegPatchDemo-USBFlash_STM32F7DISCO_v1.0.0_v2.0.0.sfbp
Briefly, to run the demo 1) load the .hex file with STM32CubeProgrammer, and 2) put the .sfbp onto a USB stick, plug it into the adapter, press reset. See the version increment from 1 to 2 and the middle image change due to the content of the secured patch file. Details are below.
The .hex file is automatically generated at the end of each build and combines the secure bootloader, the application, and content for the DISCO's QSPI flash: everything allocated to the ExtFlashSection section. Combining all the elements into one programming file makes it easy to program your devices in one step.
The .sfbp file is a secured patch - encrypted and signed with your own AES and ECDSA keys - containing only the differences between what is already on the device's internal and external flash and the new version. These differences are applied to the existing application to create a second update image located in a dedicated QSPI segment. The main application is not touched until the bootloader fully verifies (again) the reconstructed update image. In this demo, the .sfbp file contains the content for just the new "scuba diver" image and a couple of application string modifications.
Programming the .hex file
Start STM32CubeProgrammer and make sure to select an "External Loader" by clicking the icon in the bottom left area. Choose the loader for the STM32F769I-DISCO. Open the hex file downloaded from the link above or from the attachments for programming and click program. The programming procedure erases necessary internal and external flash sectors then writes the content of the hex file to the right locations, including the bootloader, application and QSPI.
Running the application
Reset the board (this happens automatically after programming) and observe this terminal output to the STLINK VCOM port at 115200 N81.
= [SBOOT] RuntimeProtections: 0
= [SBOOT] System Security Check successfully passed. Starting...
QSPI Init status=2
= [FWIMG] Slot #0 @: 8080000 / Slot #1 @: 90400000 / Block size: 40000
======================================================================
= Firmware Modules =
= =
= Secure Boot and Secure Firmware Update =
= With Delta Patching =
= for STM32F7 =
= =
= *** Bootloader *** =
======================================================================
Build Date: Dec 15 2020 10:03:36
Build Version: v2.1.0-23-g5d206f7
Anti-rollback: Enabled
= [SBOOT] STATE: WARNING: SECURE ENGINE INITIALIZATION WITH FACTORY DEFAULT VALUES!
= [SBOOT] STATE: CHECK STATUS ON RESET
INFO: A Reboot has been triggered by a Software reset!
Consecutive Boot on error counter reset
Consecutive Boot on error counter = 0
Consecutive Boot on error counter updated
INFO: Last execution status before Reboot was:Checking Status on Reset.
INFO: Last execution detected error was:No error. Success.
= [SBOOT] STATE: CHECK NEW FIRMWARE TO DOWNLOAD
= [SBOOT] STATE: CHECK FLASH MEDIA
= [SBOOT] No valid firmware found on flash media, status=1
= [SBOOT] STATE: CHECK USER FW STATUS
= [FWIMG] No valid header found in slot 1.
A valid FW is installed in the active slot - version: 4096
= [SBOOT] STATE: EXECUTE USER FIRMWARE
======================================================================
= Firmware Modules FM-SBSFU =
= https://firmwaremodules.com =
= =
= Secure Boot and Secure Firmware Update =
= For STM32F7 =
= Multi-Segment QSPI Delta Patch FM-SBSFU Demo =
= With USB Flash Loader =
= =
= *** Demonstration Application *** =
======================================================================
FW Version: 1.0.0
FW Build: v2.1.0-23-g5d206f7
FW Tag: 0x6D70087E
QSPI string: This is a message from QSPI!
Images @ 0x90000000 0x9001c28a 0x90038514
=================== Main Menu ============================
Download a new Fw Image ------------------------------- 1
Read Application Info ----------------------------- 2
On the screen you will see the Version 1 image set:
Each image is about 112 KB. The .sfbp patch file changes only some text strings and the middle image and therefore it is about 113 KB. The text strings reside in MCU flash while the images reside in QSPI flash.
Perform the Update
To perform the update, copy the update patch file MultiSegPatchDemo-USBFlash_STM32F7DISCO_v1.0.0_v2.0.0.sfbp file to a USB flash drive, insert the drive into the USB micro-A to A adapter and press the reset button. As indicated in the file's name, this patch is for updating "v1.0.0" to "v2.0.0". It is very precise: the SHA-256 hash tags of the image to be updated and the final reconstructed image is included in the patch file so as to ensure with 100% certainty that the patching process completes successfully every time or not at all in case the patch is not correct for the firmware on the device.
Transferring the patch, reconstructing the final update image, and copying overtop of the main application slot (SLOT 0) is done quickly via USB flash drive and is limited mainly by the erase times of the flash sectors involved. After pressing the reset button you will see the update from start to finish with an update progress trace as shown below:
= [SBOOT] STATE: CHECK NEW FIRMWARE TO DOWNLOAD
= [SBOOT] STATE: CHECK FLASH MEDIA
Open update file [MultiSegPatchDemo-USBFlash_STM32F7DISCO_v1.0.0_v2.0.0.sfbp] 115488 bytes
[ ] 0%
[ ] 1%
[. ] 2%
[. ] 3%
[. ] 4%
[.. ] 5%
[.. ] 6%
[.. ] 7%
[... ] 8%
[... ] 9%
[... ] 10%
[.... ] 11%
[.... ] 12%
[.... ] 13%
[.... ] 14%
[..... ] 15%
[..... ] 16%
[..... ] 17%
[...... ] 18%
[...... ] 19%
[...... ] 20%
[....... ] 21%
[....... ] 22%
[....... ] 23%
[........ ] 24%
[........ ] 25%
[........ ] 26%
[......... ] 27%
[......... ] 28%
[......... ] 29%
[.......... ] 30%
[.......... ] 31%
[.......... ] 32%
[........... ] 33%
[........... ] 34%
[........... ] 35%
[............ ] 36%
[............ ] 37%
[............ ] 38%
[............ ] 39%
[............. ] 40%
[............. ] 41%
[............. ] 42%
[.............. ] 43%
[.............. ] 44%
[.............. ] 45%
[............... ] 46%
[............... ] 47%
[............... ] 48%
[................ ] 49%
[................ ] 50%
= [SBOOT] Firmware patched from flash media and ready to install, status=1
= [SBOOT] STATE: CHECK USER FW STATUS
= [FWIMG] Valid header found in slot 1. Version=8192 Size=390064
= [FWIMG] Valid installation trigger header found in slot 1.
Potentially valid backup or update firmware present and ready in SLOT 1 - see if it needs to and can be installed.
= [SBOOT] STATE: INSTALL NEW USER FIRMWARE
[................ ] 50%
[................ ] 51%
[................. ] 52%
[................. ] 53%
[................. ] 54%
[.................. ] 55%
[.................. ] 56%
[.................. ] 57%
[................... ] 58%
[................... ] 59%
[................... ] 60%
[.................... ] 61%
[.................... ] 62%
[.................... ] 63%
[.................... ] 64%
[..................... ] 65%
[..................... ] 66%
[..................... ] 67%
[...................... ] 68%
[...................... ] 69%
[...................... ] 70%
[....................... ] 71%
[....................... ] 72%
[....................... ] 73%
[........................ ] 74%
[........................ ] 75%
[........................ ] 76%
[......................... ] 77%
[......................... ] 78%
[......................... ] 79%
[.......................... ] 80%
[.......................... ] 81%
[.......................... ] 82%
[........................... ] 83%
[........................... ] 84%
[........................... ] 85%
[............................ ] 86%
[............................ ] 87%
[............................ ] 88%
[............................ ] 89%
[............................. ] 90%
[............................. ] 91%
[............................. ] 92%
[.............................. ] 93%
[.............................. ] 94%
[.............................. ] 95%
[............................... ] 96%
[............................... ] 97%
[............................... ] 98%
[................................] 99%
[................................] 100%
= [FWIMG] FW installation succeeded.
= [SBOOT] STATE: VERIFY USER FW SIGNATURE
= [SBOOT] STATE: EXECUTE USER FIRMWARE
======================================================================
= Firmware Modules FM-SBSFU =
= https://firmwaremodules.com =
= =
= Secure Boot and Secure Firmware Update =
= For STM32F7 =
= Multi-Segment QSPI Delta Patch FM-SBSFU Demo =
= With USB Flash Loader =
= =
= *** Demonstration Application *** =
======================================================================
FW Version: 2.0.0
FW Build: v2.1.0-23-g5d206f7
FW Tag: 0x7DCDB900
QSPI string: This is a message from QSPI!
Images @ 0x90000000 0x9001c28a 0x90038514
Bootloader
The FM-SBSFU bootloader takes over on every device boot. It looks for a valid, complete and reconstructed update image in a Download SLOT 1 in QSPI flash. If it finds such an image, as it does now after performing the USB flash update of the patch, it will compare the version numbers of the new firmware to the active firmware. If the new firmware is higher, e.g. 2.0.0 vs 1.0.0 or 1.0.1 vs 1.0.0, then an update is performed: the active image is erased and the new image is copied over. If the active image is corrupted and only if the new firmware has the same or higher version, the update is performed. If the active image is missing, then the update is performed from any version. The active image header is located inside the device's secured internal flash and this cannot be manipulated to cause an older version of the firmware located in unsecured external flash to be installed.
Note that when performing an update from the SBSFU (bootloader) as we are doing with the USB flash drive method presented here, the patch and update procedure occurs in-line without a reset in between. The new application is launched right away. On the other hand, if the main application is downloading and installing a patch using some OTA update method (e.g. over cellular HTTP), it obviously cannot overwrite itself and must reset for the bootloader to take over and perform the update as described above.
The FM-SBSFU bootloader's job is to ensure that a valid and the most recent version of firmware is active on the device. If the main application becomes corrupt for any reason, the bootloader corrects that by re-installing the main application (subject to version checks). The bootloader performs all authentication checks using ECDSA to ensure that only your firmware signed by your build system gets onto your devices. These same checks are done by both the patching system and by the bootloader to ensure maximum security, uptime and availability of your devices.
When the update has completed, the application is launched and on the display you will notice the middle image has changed to that of the scuba diver!
The patch update of the TouchGFX application on QSPI flash has been successfully completed. Imagine how these techniques could be applied to your IoT and embedded system product with external QSPI flash!
Demo Flash Layout
Now that you've seen the demo application, we can talk about the flash layout in a bit more detail. The demo application is placed in MCU internal flash and board QSPI flash in the following way. This placement is automatically setup by the build tools and embodied in the .hex file and bootloader and patching system.
The ExtFlashSection (Resources) content is mapped to MCU memory address (0x9000 0000) which is reserved for the QSPI in memory mapped mode. Memory mapped mode allows the firmware instructions to access data from QSPI as if it was in any other memory space like flash (0x0800 0000) or SRAM (0x2000 0000). The benefit is that access to GUI resources like images does not have to go through a SPI flash firmware driver layer: the STM32 MCU QSPI peripheral handles that. While TouchGFX operates in this mode, the bootloader and patching system use direct QSPI mode to perform reads, writes and erases.
You've learned about a series of advanced techniques to seamlessly deploy and update firmware in the field on projects that combine internal and external flash and a USB host to update via USB flash drive.
If you want to learn more and/or are interested in getting this system installed faster and for less cost than doing it yourself, check out our website at firmwaremodules.com or send me a DM here on Hackster.io.
Check out our FM-SBSFU projects:
Comments