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 14 15:59:02 2014 +0000
Revision:
1:208de08b1a19
Parent:
0:e221363f7942
Child:
3:c69fff55fc60
Unconditionally try to remove the old bin file when a new one has been downloaded.; Add a few more warning messages.; Provide a placeholder for an integrity check of the new download.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:e221363f7942 1
WiredHome 0:e221363f7942 2 // Software Update via Ethernet from forum -
WiredHome 0:e221363f7942 3 // http://mbed.org/forum/mbed/topic/1183/
WiredHome 1:208de08b1a19 4 //
WiredHome 0:e221363f7942 5 #include "mbed.h"
WiredHome 0:e221363f7942 6 #include "SWUpdate.h"
WiredHome 0:e221363f7942 7 #include "HTTPClient.h"
WiredHome 0:e221363f7942 8 #include "HTTPText.h"
WiredHome 0:e221363f7942 9 #include "HTTPFile.h"
WiredHome 0:e221363f7942 10 #include <stdio.h>
WiredHome 0:e221363f7942 11
WiredHome 0:e221363f7942 12 extern "C" void mbed_reset();
WiredHome 0:e221363f7942 13
WiredHome 0:e221363f7942 14 #define DEBUG "SWup"
WiredHome 0:e221363f7942 15 #include <cstdio>
WiredHome 0:e221363f7942 16 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 0:e221363f7942 17 #define DBG(x, ...) std::printf("[DBG %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 0:e221363f7942 18 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 0:e221363f7942 19 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 0:e221363f7942 20 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 0:e221363f7942 21 #else
WiredHome 0:e221363f7942 22 #define DBG(x, ...)
WiredHome 0:e221363f7942 23 #define WARN(x, ...)
WiredHome 0:e221363f7942 24 #define ERR(x, ...)
WiredHome 0:e221363f7942 25 #define INFO(x, ...)
WiredHome 0:e221363f7942 26 #endif
WiredHome 0:e221363f7942 27
WiredHome 1:208de08b1a19 28 static bool PassesIntegrityCheck(const char * fname) {
WiredHome 1:208de08b1a19 29 return true;
WiredHome 1:208de08b1a19 30 }
WiredHome 1:208de08b1a19 31
WiredHome 0:e221363f7942 32 bool SoftwareUpdate(const char *url, const char * name, Reboot_T reboot) {
WiredHome 0:e221363f7942 33 HTTPClient http;
WiredHome 0:e221363f7942 34 //http.setTimeout( 15000 );
WiredHome 0:e221363f7942 35 char fqurl[150]; // fully qualified url
WiredHome 0:e221363f7942 36 char verfn[32]; // local version file
WiredHome 0:e221363f7942 37 char fwfn[32];
WiredHome 0:e221363f7942 38 bool result = false; // many things can go wrong, assume failure
WiredHome 0:e221363f7942 39 //char *verfn = "/local/VERSION.TXT";
WiredHome 0:e221363f7942 40 char buf[50];
WiredHome 0:e221363f7942 41
WiredHome 0:e221363f7942 42 INFO("SoftwareUpdate(%s,%s)", url, name);
WiredHome 0:e221363f7942 43 snprintf(verfn, 32, "/local/%s.ver", name);
WiredHome 0:e221363f7942 44
WiredHome 0:e221363f7942 45 /* Read installed version string */
WiredHome 0:e221363f7942 46 int inst_ver = -1;
WiredHome 0:e221363f7942 47 FILE *fv = fopen(verfn, "r");
WiredHome 0:e221363f7942 48 if (fv) {
WiredHome 0:e221363f7942 49 fscanf(fv, "%d", &inst_ver);
WiredHome 0:e221363f7942 50 fclose(fv);
WiredHome 0:e221363f7942 51 }
WiredHome 0:e221363f7942 52 INFO(" Installed version: %d", inst_ver);
WiredHome 0:e221363f7942 53
WiredHome 0:e221363f7942 54 /* Download latest version string */
WiredHome 0:e221363f7942 55 HTTPText server_ver("test message");
WiredHome 0:e221363f7942 56 snprintf(fqurl, 150, "%s/%s.txt", url, name);
WiredHome 0:e221363f7942 57 HTTPResult r = http.get(fqurl, buf, sizeof(buf));
WiredHome 0:e221363f7942 58 if (r == HTTP_OK) {
WiredHome 0:e221363f7942 59 int latest_ver = -1;
WiredHome 0:e221363f7942 60 INFO(" read {%s}", buf);
WiredHome 0:e221363f7942 61 sscanf(buf, "%d", &latest_ver);
WiredHome 0:e221363f7942 62 INFO(" web version: %d", latest_ver);
WiredHome 0:e221363f7942 63 if (inst_ver != latest_ver) {
WiredHome 0:e221363f7942 64 INFO(" Downloading new firmware...");
WiredHome 0:e221363f7942 65 sprintf(fwfn, "/local/%s%d.BIN", name, latest_ver);
WiredHome 0:e221363f7942 66 snprintf(fqurl, 150, "%s/%s.bin", url, name);
WiredHome 0:e221363f7942 67
WiredHome 0:e221363f7942 68 HTTPFile latest(fwfn);
WiredHome 0:e221363f7942 69 r = http.get(fqurl, &latest);
WiredHome 0:e221363f7942 70 if (r == HTTP_OK) {
WiredHome 1:208de08b1a19 71 // Check the integrity of the freshly downloaded file,
WiredHome 1:208de08b1a19 72 // before swapping out the old version.
WiredHome 1:208de08b1a19 73 // ... to appear here ...
WiredHome 1:208de08b1a19 74 if (PassesIntegrityCheck(fwfn)) {
WiredHome 1:208de08b1a19 75 sprintf(fwfn, "/local/%s%d.BIN", name, inst_ver);
WiredHome 1:208de08b1a19 76 INFO(" Firmware downloaded, removing old version (%s).", fwfn);
WiredHome 1:208de08b1a19 77 if (remove(fwfn)) {
WiredHome 1:208de08b1a19 78 ERR(" *** Failed to remove old version. ***");
WiredHome 1:208de08b1a19 79 }
WiredHome 1:208de08b1a19 80 INFO("Updating stored version number.");
WiredHome 1:208de08b1a19 81 fv = fopen(verfn, "w");
WiredHome 1:208de08b1a19 82 if (fv) {
WiredHome 1:208de08b1a19 83 int fr = fputs(buf, fv);
WiredHome 1:208de08b1a19 84 if (fr < 0) {
WiredHome 1:208de08b1a19 85 ERR("Failed (%d) to update stored version number.", fr);
WiredHome 1:208de08b1a19 86 fclose( fv );
WiredHome 1:208de08b1a19 87 } else {
WiredHome 1:208de08b1a19 88 fclose( fv );
WiredHome 1:208de08b1a19 89 if (reboot == AUTO_REBOOT) {
WiredHome 1:208de08b1a19 90 WARN("Resetting...\n");
WiredHome 1:208de08b1a19 91 wait_ms(200);
WiredHome 1:208de08b1a19 92 mbed_reset();
WiredHome 1:208de08b1a19 93 }
WiredHome 1:208de08b1a19 94 result = true;
WiredHome 1:208de08b1a19 95 }
WiredHome 0:e221363f7942 96 } else {
WiredHome 1:208de08b1a19 97 WARN("Failed to update local version info in %s.", verfn);
WiredHome 0:e221363f7942 98 }
WiredHome 1:208de08b1a19 99 } else {
WiredHome 1:208de08b1a19 100 WARN("New file {%s} did not pass integrity check.", fwfn);
WiredHome 0:e221363f7942 101 }
WiredHome 0:e221363f7942 102 } else {
WiredHome 1:208de08b1a19 103 WARN("Failed to download lastest firmware.");
WiredHome 0:e221363f7942 104 }
WiredHome 0:e221363f7942 105 }
WiredHome 0:e221363f7942 106 } else {
WiredHome 1:208de08b1a19 107 WARN("Failed to download online firmware version number.");
WiredHome 0:e221363f7942 108 }
WiredHome 0:e221363f7942 109 return result;
WiredHome 0:e221363f7942 110 }