Tip: With a commercial account, you can have up to 1,000 firmware images at a time, instead of 10. See Choosing your account type for more information about the other benefits of commercial accounts and how to upgrade a free account to a commercial account.
- Ensure you reserve the correct memory regions.
- The user application interacts with Update client. You can provide callbacks to allow the application to approve an update, as the client tutorial explains.
Updatable firmware images
To update firmware, you need three things:
A bootloader. When the microcontroller is on, it automatically executes from the start address, which on many Mbed boards is at memory address
0x0at the beginning of the flash. The bootloader is typically placed at this location, so it gets the control first when the device boots. The bootloader is never updated. It is the singular piece of code that guarantees that only a valid firmware image ever loads on the device.
A metadata header: Contains information about the firmware, which the bootloader uses to validate the firmware before loading it. The metadata header is generated from the firmware image in two conditions:
- When you build the initial firmware image, a build tool generates the metadata header and combines the firmware image with the bootloader and the metadata header, into a single large binary.
- When Update client performs a firmware update, Update client generates a metadata header for the new candidate firmware image.
A firmware image: Contains the OS, Update client and the user application.
After you have an initial image on your device, you can generate a delta image for your update campaigns. A delta image contains the information necessary to create the new image from the old one. This means you only need to transmit the delta, not a full new image, to the device. Delta update can save bandwidth and energy for NB-IoT devices, or when installing large firmware images with only small code changes. Using a delta image can also reduce the amount of time needed for an update campaign.
You need access to the full image currently running on the device, as well as the full images of any previous versions for which you want to create a delta.
Update client and the bootloader
Update client writes new firmware in a location the bootloader can access. The bootloader's primary responsibility is to check there were no errors while Update client was writing the new firmware. To achieve this, the bootloader performs the following actions:
Checks the integrity of the active firmware by calculating the hash of the active image and comparing it to the one in the metadata header.
Handles new images, if any exist:
Checks the integrity of the new image by checking the hash against its corresponding metadata header.
If newer, applicable images exist, the bootloader copies the newest image to the active application memory region.
Forwards the control to the start of the application binary. The application containing Update client has now gained control and can receive further updates.
The Update client in the application is inactive until it receives a notification from one of its update sources.
- The Update client receives a notification from Device Management and downloads the manifest.
- Verifies the manifest authenticity and applicability.
- Parses the manifest to obtain the firmware URI.
- Fetches the firmware from one of its update sources.
- Writes the firmware into a spare image slot in storage.
- Reboots and hands control back to the bootloader.
Flash layout for the example bootloader
The bootloader expects to have the following internal flash layout if KVSTORE provides the Root of Trust:
+--------------------------+ | | | | | | |Firmware Candidate Storage| | | | | | | +--------------------------+ <-+ update-client.storage-address | | | KVSTORE | | | +--------------------------+ <-+ storage_tdb_internal.internal_base_address | | | | | | | Active App | | | | | | | +--------------------------+ <-+ mbed-bootloader.application-start-address |Active App Metadata Header| +--------------------------+ <-+ update-client.application-details | | | Bootloader | | | +--------------------------+ <-+ 0