In-Field Update

Last modified October 9, 2015

Required

Tutorials:  First NETMF Project

Introduction

One of GHI Electronics's additions to NETMF includes the In-Field Update (IFU) class allowing devices to be updated in the field. This feature is independent from where the new updates come from. They can be obtained over the network or from a file. Developers can even add encryption and integrity checking algorithms as necessary.

Once the data is available, it is passed on to IFU, which stores it internally in RAM. Once all of the data is received and loaded by the developer, a single call will wipe the flash and write the new files. Only the regions that are being updated are erased.

Warning

The final stage will erase the flash and write the new data. This can take some time depending on the board. Losing power during this process will cause the update to fail and require the device to be updated manually.

Extracting an Existing Application

Creating a hex file to flash to your deployed board is easy. For example, you may have a board that has been placed in the field (mall kiosk, traffic signal, etc) that you would like to update the firmware or application on or add a new feature, but you do not have the ability to access this board as it is placed in a permanent enclosure. All you have to do is deploy the new version of the program to another board of the same type. Once this is done, open MFDeploy, select USB, then in the menu select Target->Application Deployment->Create Application Deployment.

Tip

If you would like the next version of your application to have the same update ability, be sure to include the update code in it as well.

Select the name of the file that you would like to use and where to save it.

Once this is done, you can place this file on an SD card and insert it into your device, or you can send it to you device over a network. The next section will demonstrate how to load the files in and perform the update.

Getting Started

The following example shows you how to load data into IFU and then flash the device. It requires the GHI.Hardware assembly and assumes that you have already mounted an SD card. Since firmwares can be pretty big, they cannot be held in memory in their entirety so we only load portions of the file at a time.

using GHI.Processor;
using System.IO;

public class Program
{
    public const int BLOCK_SIZE = 65536;

    public static void FlashFirmware()
    {
      	// Reserve the memory needed to buffer the update.
      	// A lot of RAM is needed so it is recommended to do this at the program start.
        InFieldUpdate.Initialize(InFieldUpdate.Types.Firmware | InFieldUpdate.Types.Configuration);

        // Start loading the new firmware on the RAM reserved in last step.
      	// Nothing is written to FLASH In this stage. Power loss and failures are okay
      	// Simply abort this stage any way you like!
      	// Files can come from Storage, from network, from serial bus and any Other way.
      	LoadFile("\\SD\\Config.hex", InFieldUpdate.Types.Configuration);
        LoadFile("\\SD\\Firmware.hex", InFieldUpdate.Types.Firmware);
        LoadFile("\\SD\\Firmware2.hex", InFieldUpdate.Types.Firmware); //Only if your device has two firmware files.
      
		// This method will copy The new firmware from RAM to FLASH.
      	// This function will not return But will reset the system when done.
      	// Power loss during Before this function resets the system quill result in a corrupted firmware.
      	// A manual update will be needed if this method failed, due to power loss for example.
        InFieldUpdate.FlashAndReset();
    }

    public static void LoadFile(string filename, InFieldUpdate.Types type)
    {
        using (var stream = new FileStream(filename, FileMode.Open))
        {
            var data = new byte[BLOCK_SIZE];

            for (int i = 0; i < stream.Length / BLOCK_SIZE; i++)
            {
                stream.Read(data, 0, BLOCK_SIZE);
                InFieldUpdate.Load(type, data, BLOCK_SIZE);
            }

            stream.Read(data, 0, (int)stream.Length % BLOCK_SIZE);
            InFieldUpdate.Load(type, data, (int)stream.Length % BLOCK_SIZE);
        }
    }
}
Leave feedback about this document.
Let us know if the information presented here was accurate, helpful and if you have any suggestions.
Leave feedback about this document.
Let us know if the information presented here was accurate, helpful and if you have any suggestions.

* Indicates required fields.
This form is only for feedback not support.
Review our how to find information guide on locating helpful resources.