SystemUpdate fails

I want to update firmware from network. I don’t want to use a SD card. The firmware size is about 1.7MB.

So here is my thought:

  1. SystemUpdate.ApplicationUpdate.Start()
  2. Download data from web site and use SystemUpdate.ApplicationUpdate.Write() to write data into flash.
  3. SystemUpdate.ApplicationUpdate.End();

But the application might get error in step 2. Because if the network is broken, the application does a incomplete update.

Could the EMX board be able to rollback to previous firmware?

When you run the write step in IFU, it actually only buffers the firmware internally and nothing is written on flash. This should be explained in docs I believe

But I think it behaves out of my assumption.


public static void Main()
        {
            SystemUpdate.SystemUpdateMode mode = SystemUpdate.GetMode();
            
            Log("EMX starts. Mode: " + mode.ToString());
            
            // Allow firmware on the board to be upgradable.
            if (mode == SystemUpdate.SystemUpdateMode.NonFormatted)
            {
                SystemUpdate.EnableBootloader();

                // Force a hard reboot
                PowerState.RebootDevice(false);
            }

            // Start to upgrade firmware
            if (mode == SystemUpdate.SystemUpdateMode.Bootloader)
            {
                Log("Start to upgrade ...");
                // Force mount all removable disks
                ...

                if (firmwarePath.Length > 0)
                {
                    // Start to upgrade
                    try
                    {
                        SystemUpdate.ApplicationUpdate.Start();

                        FileStream fs = new FileStream(firmwarePath, FileMode.Open, FileAccess.Read);
                        byte[] buffer = new byte[10 * 1024];
                        int len = 0;

                        do
                        {
                            len = fs.Read(buffer, 0, buffer.Length);
                            SystemUpdate.ApplicationUpdate.Write(buffer, 0, len);

                            throw new Exception(); // throw an exception to interrupt updating
                        } while (len == buffer.Length);

                        SystemUpdate.ApplicationUpdate.End();
                    }
                    catch (Exception ex)
                    {
                        Log("Failed to upgrade.");
                    }
                  
                }

                //Restart
                SystemUpdate.AccessApplication();
            }

            if (mode == SystemUpdate.SystemUpdateMode.Application)
            {
                if (PersistentStorage.DetectSDCard())
                {
                    PersistentStorage ps = new PersistentStorage("SD");
                    ps.MountFileSystem();

                    if (File.Exists("\\SD\\Firmware.hex"))
                    {
                        Log("Prepare to upgrade. Rebooting ...");
                        SystemUpdate.AccessBootloader();
                    }
                }
            }

            Thread.Sleep(5000);
}

I write the code above in main function. It reads firmware from a micro SD card and upgrade it to the EMX board. I use an exception in write loop to interrupt the upgrading. The firmware size is 260+ KB, so in my code it only write 10KB to EMX.

After I reboot the EMX board, I can see a debug message from MFDeploy:
This is the version. You have succeeded to upgrade the firmware.

This message is the only Debug.Print message of the firmware in SD card.

In ApplicationUpdate:
Once you hit Start(), the main application is erased.
There is no rollback option, but you should NOT call AccessApplication mode until everything is updated correctly.
So when a failure happens during transferring the application, simply reboot the device and it will go into bootloader mode or call End() then Start() again to re-update…

In CompleteUpdate it is different. Nothing is updated until you call End().

From my test, I believe CompleteUpdate.Start() erases the main application either. I use CompleteUpdate instead of ApplicationUpdate in my code, after a fail update, I get the message from MFDeploy:

Ready.
Cannot find any entrypoint!
Done.
Waiting for debug commands…
No debugger!

If I use ApplicationUpdate, the message from MFDeploy is:

Ready.
Hello, this is the new version. …

CompleteUpdate does not erase until End(). If you still have problems please provide the new code.

No, I threw an exception in loop Write() method, it never goes to End() method. The new code is the same as my code above, just use ComplateUpdate instead of ApplicationUpdate.