Software Update via Ethernet - the mbed application can pull down an updated application binary from a web server and activate that binary. This library works only with the LPC1768, as it relies on the magic-chip boot-loader mechanism.

Dependents:   WattEye X10Svr PUB_SWUpdate

Success!! With this library, a network connection, and a web server hosting a new binary image, you can update the mbed firmware over the air (FOTA) - well, at least via Ethernet so far.

As of March 2015, it has been tested with the following mbed official libraries:

And a custom derivation:

  • HTTPClient v33, v32, which includes a custom HTTPFile.

Part of the update process involves checking the integrity of the downloaded binary file, for both a checksum and the program (file) size. To create this additional information, a small perl script is used (the important part is only 20 lines of code). See the documentation in the header file.

After the new binary is successfully downloaded, the checksum and the size are evaluated and if correct, then the old binary file is removed (this is the only way to cause the new binary to activate).

The mbed can then be automatically reset to activate the new image, or this may be deferred in case there is some other process necessary for an orderly restart.

Details are in the SWUpdate header file, and PUB_SWUpdate is a publicly accessible demonstration program for this library.

Committer:
WiredHome
Date:
Sat Jun 21 19:31:37 2014 +0000
Revision:
11:4ef0309135e6
Parent:
10:78d727e8d0de
Child:
12:f1fdf8cabbc4
another documentation update.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 11:4ef0309135e6 1 /// @file Automatic Software Update via the network.
WiredHome 9:73067ef14c30 2 ///
WiredHome 9:73067ef14c30 3 /// This library provides a reasonably simple interface to updating sofware
WiredHome 10:78d727e8d0de 4 /// semi-automatically via the network. It does that by querying a web server
WiredHome 10:78d727e8d0de 5 /// upon which you have placed an updated version of the embedded software
WiredHome 10:78d727e8d0de 6 /// application. Upon finding something there, it will determine if it is
WiredHome 10:78d727e8d0de 7 /// a different version than the one you current have installed and it
WiredHome 10:78d727e8d0de 8 /// will try to download the software. If that succeeds, then it can
WiredHome 10:78d727e8d0de 9 /// optionally reboot to activate the new software.
WiredHome 10:78d727e8d0de 10 ///
WiredHome 10:78d727e8d0de 11 /// While the name shown in the examples here is "myprog", this is unimportant.
WiredHome 10:78d727e8d0de 12 /// Your application will have a name of your choosing, which you will
WiredHome 10:78d727e8d0de 13 /// use in the API.
WiredHome 10:78d727e8d0de 14 ///
WiredHome 10:78d727e8d0de 15 /// Local File System Files:
WiredHome 10:78d727e8d0de 16 ///
WiredHome 10:78d727e8d0de 17 /// The files of interest on the local file system are as follows:
WiredHome 10:78d727e8d0de 18 ///
WiredHome 10:78d727e8d0de 19 /// @li myprog_23.bin - The actual application binary file that is currently
WiredHome 10:78d727e8d0de 20 /// executing. In this case, this is the 23rd version that
WiredHome 10:78d727e8d0de 21 /// has been installed. You can go to 99 after which you might
WiredHome 10:78d727e8d0de 22 /// want to start over.
WiredHome 10:78d727e8d0de 23 /// @li myprog.ver - A text file, maintained by this software update
WiredHome 10:78d727e8d0de 24 /// application, that was downloaded from the server with
WiredHome 10:78d727e8d0de 25 /// application version 23.
WiredHome 10:78d727e8d0de 26 ///
WiredHome 10:78d727e8d0de 27 /// If "myprog.ver" does not exist, it will assume that the server has a
WiredHome 10:78d727e8d0de 28 /// newer application, so it will be downloaded and activated (even if all
WiredHome 10:78d727e8d0de 29 /// it does is to replace the existing myprog_23.bin file).
WiredHome 10:78d727e8d0de 30 ///
WiredHome 10:78d727e8d0de 31 /// Web Server Files:
WiredHome 10:78d727e8d0de 32 ///
WiredHome 10:78d727e8d0de 33 /// The files on the web server are as follows.
WiredHome 10:78d727e8d0de 34 ///
WiredHome 10:78d727e8d0de 35 /// @li myprog.bin - The latest version of the application binary file.
WiredHome 10:78d727e8d0de 36 /// Note that this file does not have any version number
WiredHome 10:78d727e8d0de 37 /// embedded into its filename as is the case on the local
WiredHome 10:78d727e8d0de 38 /// file system.
WiredHome 10:78d727e8d0de 39 /// @li myprog.txt - A corresponding text file. The root name must match
WiredHome 10:78d727e8d0de 40 /// that of the binary file.
WiredHome 10:78d727e8d0de 41 ///
WiredHome 10:78d727e8d0de 42 /// The myprog.txt file shall have 3 comma-separated numbers in it.
WiredHome 10:78d727e8d0de 43 /// version,checksum,filesize (e.g. "23,41384,107996").
WiredHome 10:78d727e8d0de 44 ///
WiredHome 10:78d727e8d0de 45 /// @li version is a simple number. If the number is different than
WiredHome 10:78d727e8d0de 46 /// what is stored on the local file system, then the program
WiredHome 10:78d727e8d0de 47 /// will be updated (even if the server number is lower).
WiredHome 10:78d727e8d0de 48 /// This bidirectional "update" can let you downgrade.
WiredHome 10:78d727e8d0de 49 /// @li checksum is the decimal representation of a simple 16-bit checksum.
WiredHome 10:78d727e8d0de 50 /// @li filesize is the decimal representation of the size of the file.
WiredHome 10:78d727e8d0de 51 ///
WiredHome 10:78d727e8d0de 52 /// Variations:
WiredHome 10:78d727e8d0de 53 ///
WiredHome 10:78d727e8d0de 54 /// Within that single web server folder, you could have several apps -
WiredHome 10:78d727e8d0de 55 /// @li SensorNode.bin, SensorNode.txt
WiredHome 10:78d727e8d0de 56 /// @li SensorNode_B.bin, SensorNode_B.txt
WiredHome 10:78d727e8d0de 57 /// @li SensorDisplay.bin, SensorDisplay.txt
WiredHome 10:78d727e8d0de 58 ///
WiredHome 10:78d727e8d0de 59 /// In this example, perhaps your first version was called SensorNode, but
WiredHome 10:78d727e8d0de 60 /// with a small hardware design change, you have a new "model B" version.
WiredHome 10:78d727e8d0de 61 /// This example also assumes that you have a need to maintain two separate
WiredHome 10:78d727e8d0de 62 /// applications, one for each hardware version.
WiredHome 10:78d727e8d0de 63 ///
WiredHome 10:78d727e8d0de 64 /// You can create the server "myprog.txt" file with this perl script (not
WiredHome 10:78d727e8d0de 65 /// every detail is shown, but it should be easy to figure out).
WiredHome 10:78d727e8d0de 66 /// @code
WiredHome 10:78d727e8d0de 67 /// # Read current .txt file
WiredHome 10:78d727e8d0de 68 /// open (FT, "<$txt") || die("Can't read $txt.");
WiredHome 10:78d727e8d0de 69 /// $ver = <FT>; chomp $ver; close FT;
WiredHome 10:78d727e8d0de 70 /// $ver =~ s/(\d+),.*/$1/;
WiredHome 10:78d727e8d0de 71 /// print "Current Version is {$ver}\n";
WiredHome 10:78d727e8d0de 72 ///
WiredHome 10:78d727e8d0de 73 /// # Read the [assumed new] .bin file
WiredHome 10:78d727e8d0de 74 /// open (FB, "<$bin") || die("Can't read $bin.");
WiredHome 10:78d727e8d0de 75 /// binmode FB;
WiredHome 10:78d727e8d0de 76 /// while (sysread(FB, $c, 1))
WiredHome 10:78d727e8d0de 77 /// {
WiredHome 10:78d727e8d0de 78 /// $cksum = ($cksum + ord($c)) & 0xFFFF;
WiredHome 10:78d727e8d0de 79 /// $byteCount++;
WiredHome 10:78d727e8d0de 80 /// }
WiredHome 10:78d727e8d0de 81 /// close FB;
WiredHome 10:78d727e8d0de 82 /// # Advance version number and write the new .txt file
WiredHome 10:78d727e8d0de 83 /// $ver++; print "$ver Checksum is $cksum over $byteCount bytes.\n";
WiredHome 10:78d727e8d0de 84 /// open (FT, ">$txt") || die("Can't write update to $txt.");
WiredHome 10:78d727e8d0de 85 /// printf(FT "%d,%d,%d\n", $ver, $cksum,$byteCount);
WiredHome 10:78d727e8d0de 86 /// close FT;
WiredHome 10:78d727e8d0de 87 /// @endcode
WiredHome 4:1a3656ae80dc 88 ///
WiredHome 0:e221363f7942 89 #include "mbed.h"
WiredHome 0:e221363f7942 90
WiredHome 0:e221363f7942 91 #ifndef SWUPDATE_H
WiredHome 0:e221363f7942 92 #define SWUPDATE_H
WiredHome 0:e221363f7942 93
WiredHome 9:73067ef14c30 94 // This defines the maximum string length for a fully qualified
WiredHome 9:73067ef14c30 95 // filename. Usually, this will be pretty short
WiredHome 9:73067ef14c30 96 // (e.g. "/local/myprogramname.bin"), but we want to be generous.
WiredHome 9:73067ef14c30 97 #define SW_MAX_FQFN 80
WiredHome 9:73067ef14c30 98
WiredHome 9:73067ef14c30 99 // This defines the maximum string length for the url, including
WiredHome 9:73067ef14c30 100 // the base filename of interest.
WiredHome 9:73067ef14c30 101 #define SW_MAX_URL 150
WiredHome 9:73067ef14c30 102
WiredHome 1:208de08b1a19 103 /// After downloading, the user can choose what happens next.
WiredHome 0:e221363f7942 104 typedef enum {
WiredHome 6:6025fddc1af9 105 DEFER_REBOOT, ///< Do not reboot to activate the new firmware.
WiredHome 6:6025fddc1af9 106 AUTO_REBOOT ///< Automatically reboot to activate the new firmware.
WiredHome 0:e221363f7942 107 } Reboot_T;
WiredHome 0:e221363f7942 108
WiredHome 9:73067ef14c30 109 /// Bit-Field return codes from the SoftwareUpdate API.
WiredHome 9:73067ef14c30 110 ///
WiredHome 9:73067ef14c30 111 /// Various things can go wrong in the software update process. The return
WiredHome 9:73067ef14c30 112 /// value is a bit-field that flags the possibilities.
WiredHome 9:73067ef14c30 113 typedef enum {
WiredHome 9:73067ef14c30 114 SWUP_OK = 0x00, ///< Software Update succeeded as planned.
WiredHome 9:73067ef14c30 115 SWUP_SAME_VER = 0x01, ///< Online version is the same as the installed version.
WiredHome 9:73067ef14c30 116 SWUP_BAD_URL = 0x02, ///< Bad URL provided, File missing on server, etc.
WiredHome 9:73067ef14c30 117 SWUP_OLD_STUCK = 0x04, ///< Old file could not be removed,
WiredHome 9:73067ef14c30 118 SWUP_VER_STUCK = 0x08, ///< Old version number could not be updated.
WiredHome 9:73067ef14c30 119 SWUP_VWRITE_FAILED = 0x10, ///< Can't open for write the version tracking file.
WiredHome 9:73067ef14c30 120 SWUP_INTEGRITY_FAILED = 0x20, ///< Integrity check of downloaded file failed.
WiredHome 9:73067ef14c30 121 SWUP_HTTP_ERR = 0x40, ///< HTTP get returned an error
WiredHome 9:73067ef14c30 122 } SWUpdate_T;
WiredHome 9:73067ef14c30 123
WiredHome 10:78d727e8d0de 124
WiredHome 10:78d727e8d0de 125 /// To perform the software update, we simply give this API the web
WiredHome 10:78d727e8d0de 126 /// server URL that is hosting the embedded software. We also give it
WiredHome 10:78d727e8d0de 127 /// the "root" name of the file of interest, which permits you to
WiredHome 10:78d727e8d0de 128 /// have different applications served from the same location.
WiredHome 10:78d727e8d0de 129 /// One optional parameter lets you decide what happens if a new
WiredHome 10:78d727e8d0de 130 /// version is installed - automatically reboot to launch it, or
WiredHome 10:78d727e8d0de 131 /// return to the calling program which may perform a more orderly
WiredHome 10:78d727e8d0de 132 /// reboot.
WiredHome 9:73067ef14c30 133 ///
WiredHome 9:73067ef14c30 134 /// @code
WiredHome 9:73067ef14c30 135 /// ...
WiredHome 9:73067ef14c30 136 /// if (NowIsTheTimeToCheckForSoftwareUpdates()) {
WiredHome 9:73067ef14c30 137 /// if (SWUP_OK == SoftwareUpdate("http://192.168.1.200", "myprog", DEFER_REBOOT)) {
WiredHome 9:73067ef14c30 138 /// printf("Software updated, rebooting now...\r\n");
WiredHome 9:73067ef14c30 139 /// wait_ms(5000);
WiredHome 9:73067ef14c30 140 /// mbed_reset();
WiredHome 9:73067ef14c30 141 /// }
WiredHome 9:73067ef14c30 142 /// }
WiredHome 9:73067ef14c30 143 /// ...
WiredHome 9:73067ef14c30 144 /// @endcode
WiredHome 9:73067ef14c30 145 ///
WiredHome 1:208de08b1a19 146 /// @param url is a pointer to a text string of the url from which to download.
WiredHome 1:208de08b1a19 147 /// @param name is the base filename of the binary file.
WiredHome 9:73067ef14c30 148 /// @param action determines whether to automatically reboot to activate the new bin.
WiredHome 2:ef2ac9627546 149 /// @return true if the update succeeded (and the reboot was set to DEFER_REBOOT).
WiredHome 1:208de08b1a19 150 ///
WiredHome 9:73067ef14c30 151 SWUpdate_T SoftwareUpdate(const char *url, const char * name, Reboot_T action = AUTO_REBOOT);
WiredHome 0:e221363f7942 152
WiredHome 0:e221363f7942 153 #endif // SWUPDATE_H