PineTime bootloader improvements
Introduction
This pages describes the improvements I propose to make to the bootloader and OTA to make the whole process more reliable.
My goals are:
- KISS : Keep It Stupid Simple. Simple code contains less bugs than complicated/complex code.
- As reliable as possible. 100% reliability is not feasible with the current hardware (no physical reset button, no bootloader in ROM code,...), but let's try to reach 99.9% reliability :)
- Provide a read-only factory image we'll be able to restore in case of unrecoverable errors during OTA
- Provide a way to upgrade the bootloader
- Provide a way to switch from MCUBoot to NRF bootloaders
Current memory map
Internal flash:
- Bootloader contains the MCUBoot bootloader.
- Boot log is currently not used. Can be use to provide reboot logs to the application
- App is the PRIMARY SLOT for MCUBoot : the firmware that is currently running.
- Scratch is used by MCUBoot as temporary storage for swap operation
External flash:
- Bootloader assets : boot logo
- OTA : SECONDARY SLOT for MCUBoot. During OTA, this is where the new version of the firmware is stored.
- FS : space available for the application firmware.
Changes
Factory image
The factory image is a 'light' build of InfiniTime that contains the bare minimum code to provide OTA to the user : basic UI, BLE and OTA. No apps, no fancy functionalities,... This factory image will be stored in the "bootloader assets" area of the external flash memory.
This factory image will be restored either automatically, when the bootloader detect it cannot boot from primary slot (App in internal memory) and secondary slot (OTA from exeternal). The user can also request to restore this factory image if necessary (using the button?).
Bootloader assets
Graphics can be compressed using a simple RLE encoding. RLE encoding on 1 bits (2 colors images) is very efficient (115200KB -> 1-5KB).
In order to simplify the code, the graphics will be stored into the bootloader code instead of storing them into the external flash:
- Less code. - Easier to document : 1 specific logo = bootloader mode - Do not have to worry about the dynamic size of the logo (the binary size of the graphics will vary with the content when they are RLE encoded).
Bootloader
- Display the bootloader version on the screen and expose the version to the application firmware
- Provide a way to revert the firmware to the last working version AND to the factory firmware
- Display status and progression (progress bar similar to wasp-reloader, color code,...)
- Test as much as possible
Upgrade & Reloader
The reloader is a tool that allows to upgrade the current version of the bootloader AND to switch from MCUBoot to NRF and vice versa.
How does it work ?
- Upgrade
- The reloader is first OTAed like any firmware upgrade.
- When the system resets, MCUBoot swaps the application firmware with the reloader. The reloader upgrade the current bootloader and resets the system. It does NOT flag the image as validated. It resets the MCU.
- The new version of MCUBoot notice that the last upgrade is not validated and reverts to the firmware that was running just before.
- Voilà, you're running your firmware and a new version of the bootloader
- Switch bootloader
- The reloader is first OTAed like any firmware upgrade.
- When the system resets, MCUBoot swaps the application firmware with the reloader. The reloader overwrite the current bootloader with a new one and reset.
- The new bootloader is running.
- Switch
- From InfiniTime to wasp-os : the reloader contains the NRF Bootloader and Softdevice. This bootloader provides the OTA mecanism out of the box. Wasp-os is downloaded when the NRF bootloader is running
- From wasp-os to InfiniTime : the reloader contains the factory image (infinitime-factory). The complete version of InfiniTime will be OTAed when this factory image is running.