rBoot and OTA updates
Introduction
rBoot is an open source bootloader for the ESP8266, which is now fully integrated with Sming. rBoot is a more flexible alternative to the closed source bootloader supplied by Espressif with the SDK. A bootloader allows you to have more than one application on the esp8266, either completely different apps, or different version of the same app, which can be updated over the air.
The example Basic Ota demonstrates the use of rBoot, but if you want to add it to an existing project this little tutorial will guide you.
Need to know
The esp8266 can only memory map 1MB of flash at a time, your ROM must fit within the a single 1MB block of flash.
Different 1MB blocks can be mapped at different times, so your ROM does not have to be within the first 1MB block. The support for this in rBoot is called big flash mode. A single compiled and linked ROM image can be placed at the same relative position in any 1MB block of flash.
If you have two smaller ROMs in a single 1MB of flash (your only option if you flash is 1MB or smaller) this is referred to as two ROM mode in rBoot. Each ROM needs to be separately linked to have the correct memory mapped flash offset. Examples are given below for common scenarios.
Building
The default rBoot options are perfect for a 4MB flash, so if this is what you have (e.g. an esp-12) you don’t need to do anything else. Otherwise see information below about configuration.
Run
make
as normal, rBoot and your app ROM will both be built for you.Running
make flash
will flash rBoot and the first ROM slot.
Configuring for two ROM mode
If you have a 1MB flash, you will need to have two 512KB ROM slots, both in the same 1MB block of flash. You can accommodate this by setting the appropriate hardware configuration in your project’s component.mk file:
.. code-block:: make
HWCONFIG = two-rom-mode
See Sming/Arch/Esp8266/two-rom-mode.hw
for details.
You can copy this and customise it in your project.
SPIFFS
To use SPIFFS think about where you want your SPIFFS to sit on the flash.
If you have a 4MB flash the default position is for the first ROM
to be placed in the first 1MB block and the second ROM to be placed in
the third 1MB block of flash. This leaves a whole 1MB spare after each
ROM in which you can put your SPIFFS. This is the behaviour when you
set HWCONFIG = spiffs
in your project’s component.mk file.
If you have a smaller flash the SPIFFS will have to share the 1MB block with the ROM. For example, the first part of each 1MB block may contain the ROM, and the second part the SPIFFS (but does not have to be split equally in half). So for the 4MB example you could put the SPIFFS for your first ROM at flash address at 0x100000 and the SPIFFS for your second ROM at 0x300000; in each case that is the 1MB block after the ROM.
To mount your SPIFFS at boot time add the following code to init:
String name = F("spiffs");
name += rboot_get_current_rom();
auto part = Storage::findPartition(name);
if(part) {
//debugf("trying to mount SPIFFS at %x, length %d", part.address(), part.size());
spiffs_mount(part);
} else {
debug_e("SPIFFS partition missing for slot #%u", slot);
}
Over-the-air (OTA) updates
Instead of insisting on a “one-solution-fits-all” approach, Sming provides you with the ingredients to build an OTA upgrade mechanism tailored to your application. This involves selecting a transport protocol and a backend that interacts with the flash memory. Any protocol from Sming’s rich set of network classes can be used, ranging from raw TCP sockets to HTTP, FTP, MQTT, with or without SSL, etc. To conserve program memory, you might prefer a protocol already employed by your application.
On the backend side, there is OtaUpgradeStream
from the Over-the-Air Firmware Upgrade
library, which supports multiple ROM images in one upgrade file, as well as
state-of-the-art security features like a digital signatures and encryption.
Check out the HttpServer Firmware Upload example, which demonstrates a
browser-based firmware upgrade mechanism similar to what is found in many consumer
products.
A more lightweight solution is provided by RbootOutputStream
, which
is just a thin wrapper around rBoot’s flash API, in combination with RbootHttpUpdater
,
which pulls individual ROM image from an HTTP server.