Our first experience with the .NET Micro Framework (NETMF) was on GHI Electronic's Embedded Master platform, using the .NET Micro Framework 3.0. We recently had an opportunity to use the GHI's next generation replacement for the Embedded Master, the EMX module, and the .NET Micro Framework 4.1. Both Microsoft and GHI have made many changes to the assemblies, classes and methods.
One cool new feature is the SystemUpdate class and the bootloader features that GHI added. In the NETMF 3.0, GHI allowed firmware updates, but now you have an ability to install a bootloader as well. You can deploy a custom bootloader application to the bootloader section and programmatically switch between the two.
The maximum size of the program that resides in the bootloader section is limited (for the EMX it is 192KB). Automatic updates to the application must be done from the bootloader section. Microsoft's MFDeploy tool is used to deploy applications to the bootloader just as for the main application. Whichever area the hardware is running from determines which gets written to when you deploy.
With a fresh EMX out of the box, the first step is to run the following code:
This will format the program memory into two separate application and bootloader sections.
When you are in application mode, you can force the EMX to reboot into bootloader mode with:
You can then manually deploy a bootloader application, or allow your previously written bootloader application to perform the firmware update.
When you are in bootloader mode, you can force the EMX to reboot back into application mode with:
The system will remember which mode it is in (bootloader versus application) with subsequent reboots until the mode is changed with one of the two above functions, unless the following command is used:
Enabling this mode will cause the system to always boot into the bootloader, after which the application can be reached with the AccessApplication() function.
Once in bootloader mode, the application is updated as follows:
SystemUpdate.ApplicationUpdate.Write(baFWData, iOffset, baFWData.Length);
For the Write() function, baFWData is the firmware data as a byte array, iOffset is the initial byte within the byte array (typically zero) and, the final value passed in is the number of bytes you wish to write out of the byte array (typically the entire length). For larger applications, you can continue to call the APplicationUpdate.Write() until the entire application has been written, each time passing in new data, before calling ApplicationUpdate.End().
Errors encountered during the Write() call typically mean that you are writing 'bad' data. Keep in mind that .NET Micro Framework applications have a checksum embedded in them, which will cause a fault during writes.
For our application, our general algorithm was as follows:
1. The main application makes web service calls to a central server to determine if a new application is available for download.
2. If available, the main application downloads the new application through additional web service calls in chunks. The new application is saved to an offboard flash chip.
3. The main application writes a flag to state that the firmware is ready and reboots into the bootloader mode.
4. The bootloader reads the flag, and then reads the firmware from flash and performs the update.
5. The bootloader reboots the system back into application mode.