Using In-Field Updates
The Internet of Things is made possible by low-cost embedded systems - i.e., based on single-chip microcontrollers - connected to the Internet. Internet connectivity not only allows to send sensor data or to receive actuator commands. It can also be used for remotely monitoring and controlling a device. A major example is the possibility to send a software update to a device over the Internet, rather than going there personally - which may be inconvenient if the device was placed on top of the Matterhorn.
Since release 4.2, NETMF includes a feature called MFUpdate. This is a very light-weight framework for implementing in-field updates. It provides a simple API that allows applications to implement their own update strategies: what transport to use for transmitting an update image (Internet? USB stick? SD card?); what message format to transmit the image (encrypted? signed?); how to store an image on the device (SD card? internal flash? external flash?), etc.
So MFUpdate is actually not a specific mechanism, but rather a (very small, simple and flexible) toolbox that enables you to build your own, custom update mechanisms - of course in C#. Only the bare minimum of C support code needs to be built into the NETMF firmware itself, as much as possible is pushed into the application space, resulting in maximum flexibility and high development productivity.
So far, no vendor of NETMF devices has supported MFUpdate, in spite of its minimal footprint. This has changed with the Mountaineer 4.3.1 Beta 3 firmware. It supports the Microsoft.SPOT.MFUpdate.MFFirmwareUpdate class, which allows updating the firmware (hardware abstraction layer, platform abstraction layer, common language runtime, system assemblies), the application code, or both.
Note: Microsoft also provides an MFApplicationUpdate class, which we consider untested and not supported by NETMF for STM32.
Our thanks go to Mark Munte, who investigated the MFDeploy framework in depth and contributed his work to NETMF for STM32. His insights saved us much work. Thanks, Mark!
The current implementation of Microsoft's update providers use the Config region in the microcontroller's flash memory. Unfortunately, it has a bug (Codeplex issue) that causes it to fail after about 20 updates. To recover (see below), the Config region needs to be cleaned up explicitly by the application in some way (e.g. perform a backup before and a restore after an update), or manually by flashing the ER_CONFIG.hex file in MFDeploy.
External serial Flash memory
Mountaineer boards contain a chip with 8 MB of external Flash memory, in addition to the 1 MB of Flash memory built into the STM32 microcontroller. The external Flash has not been used by the standard Mountaineer firmware so far. Starting with release 4.3.1.0, the uppermost 1 MB of the external Flash is reserved for in-field updates. In this area, a new firmware image is stored, typically as a compressed file, possibly encrypted.
Therefore, if you somehow access the external Flash chip yourself, DO NOT TOUCH the uppermost 1 MB!
Setup
Make sure that you have the new TinyBooter installed, as described here. This TinyBooter version incorporates the firmware update feature of Microsoft's MicroBooter, so that you don't need to work with two different boot loaders.
By default, the build process of Microsoft's NETMF SDK does not create update files (.nmf suffix). To obtain such update files, a so-called post-build event must be set up, which uses a tool called BuildHelper. To make it as easy as possible, we provide a comple sample solution that includes the build helper DLLs, and has the post-build event already configured.
Sample for Ethernet Mainboard
A complete sample program that uses MFUpdate can be found here. To download a zip archive with the complete solution, you can use this download link. Unzip it and move the solution directory to where you store your other NETMF projects. Then open the solution
Oberon.MFUpdate.Sample.sln
In the Demo project properties, set the Transport to USB. Then deploy the Demo program to your Mountaineer Ethernet (!) Mainboard. The red LED on the mainboard should be blinking. Then the program starts an update cycle, by storing the Update program - which it carries along in a resource - to the external flash chip. Then the board reboots. The extended TinyBooter detects the presence of an update image, switches on the blue LED, and copies the update image to the internal Flash where the firmware resides (different address for USB mainboards, see below). Then the new code is started, which simply blinks the green LED. Now you have successfully executed a firmware update, which in this case simply replaces the application program and leaves the rest of the firmware in place.
Sample for USB Mainboard
If you are using a Mountaineer USB Mainboard rather than an Ethernet mainboard, the same steps apply as described for the Ethernet mainboard, except that you first need to modify the post build event in the Update project and change the line
echo 0x080A0000 D Deploy > symdefs.txt
to
echo 0x08080000 D Deploy > symdefs.txt
Otherwise MFUpdate will deploy the firmware to the wrong address and the newly installed assembly won't be executed. The address for the Deployment region can be seen in the Erase function in MFDeploy when the device is connected.
The solution needs to be rebuilt in order for the changes to take effect.
Recovery
If something goes wrong, follow these steps to recover:
- If you are using a Mountaineer USB Mainboard, make sure you have modified the firmware target address in the post-build event in the Update project's Visual Studio properties (Build Events tab).
- In MFDeploy, erase the Deployment region where the application program resides (click on the Erase button).
- In MFDeploy, replace the Config region in the internal Flash by the clean one that comes with the Mountaineer firmware (file ER_CONFIG.hex). On a Mountaineer Ethernet Mainboard, you will have to set up the MAC address again.
Digging deeper
If you are interested in more background information, you may want to take a look at the following presentation.
A slightly outdated documentation of MFUpdate is given on Microsoft's Web site here.