Software over the Air (wired in this case) update. This program demonstrates the SW Update library.

Dependencies:   mbed HTTPClient SWUpdate mbed-rtos Watchdog EthernetInterface

Demonstrator for the SWUpdate Library library.

Steps to test and use it

  1. Revise the test program for your environment. The following lines may need to be changed:
    • const char *url = "http://192.168.1.201/mbed";
    • const char *name = "SWUp";
    • pc.baud(460800); fast, because I like a snappy terminal!
  2. Enable debug to monitor progress.
    • HTTPClient.cpp: Remove leading "" on line #define DEBUG "HTCL"
    • HTTPFile.cpp: Remove leading "" on line #define DEBUG "HTfi"
  3. Compile this program.
  4. Copy the bin file to the mbed (if this is the very first execution of this program).
  5. Save the bin file to an accessible web server (simplifying the filename is ok).
  6. Create the companion text file, which contains the version, checksum, and size of the binary. Save on the web server.
  7. Use a serial program (e.g. Tera Term), set for a matching baud-rate as configured in the program (e.g. 460.8K).
  8. Reset the mbed so the program runs.
    1. Program prints its startup banner, which includes the compile time date(and time) stamp.
  9. Press 's', which is the command for 's'oftware update check.
  10. SWUpdate library queries the server for the .txt file, assesses if there is a newer version.
    1. SWUpdate downloads the new version.
    2. SWUpdate compares the size and checksum to assess validity.
    3. SWUpdate removes all other .bin files if the new version is good.
  11. Reports the installation of the new version and reboots to activate it.

Sample Report - Debug Enabled

SW Update: Mar  8 2015, 16:57:43
***
Initializing network interface...
Connecting to network...
Ethernet connected as   192.168.1.119
Connected at 100 Mb/s

User now presses 's' to initiate the software update check.

SoftwareUpdateCheck (http://192.168.1.201/mbed) (SWUp)
[INF HTCL  94] url: http://192.168.1.201/mbed/SWUp.txt, timeout: 15000
[INF HTCL  88] url: http://192.168.1.201/mbed/SWUp.txt, timeout: 15000
[INF HTCL 148] connect(http://192.168.1.201/mbed/SWUp.txt,0,...,15000)
[INF HTCL 170] parse: [http://192.168.1.201/mbed/SWUp.txt]
... 

The server should have two files (of interest):

  • SWUp.bin
  • SWUp.txt First it sought the SWUp.txt file to assess if the currently installed version is old.

...
[DBG HTCL 412] Receiving data
[DBG HTCL 461] Retrieving 16 bytes
[INF HTCL 464] write 16,16: 26,3947,80472

[DBG HTCL 502] Completed HTTP transaction
...

It determines that the local version is out of date, so it prepares to pull down the newer version.

...
[INF HTfi  18] HTTPFile /local/SWUp26.BIN
[INF HTCL  88] url: http://192.168.1.201/mbed/SWUp.bin, timeout: 15000
[INF HTCL 148] connect(http://192.168.1.201/mbed/SWUp.bin,0,...,15000)
...

It forms the command to get the binary, and sends that to the server.

...
[DBG HTCL 557] send(GET /mbed/SWUp.bin HTTP/1.1
Host: 192.168.1.201:80
Connection: keep-alive
,77)
...

In response to that "GET" command, the server replies.

...
[DBG HTCL 374] Read header : Content-Length: 80472
[INF HTfi  66] setDataLen(80472)
...

Soon after this, the console shows the streaming process of pulling down the data and writing it to a file. As the data is binary, the console shows a combination of text and binary. Some of this garbage fools the terminal program (which was running in VT100 mode) into continuing to show binary.

...
[DBG HTCL 546] Read 213 bytes
[INF HTCL 464] write 213,78679: ¥àIÕ¥$à
[INF HTfi  40] write(213,¥àIÕ¥$à) m_len(80472), chunk 0
[INF HTfi  43]   writ:213, ftell: 1998
...

Eventually, we get to the end of this.

...
[INF HTfi  45] closing
[INF HTfi  24] close()
[DBG HTCL 502] Completed HTTP transaction
  Update installed, rebooting ...

And the new version is installed and activated. When the SWUpdate is working as intended, debug can be disabled.

Debug Disabled

This text is all emitted from the sample program, not the SWUpdate library, after 's' is pressed to initiate the software update check.

SoftwareUpdateCheck (http://192.168.1.201/mbed) (SWUp)
  Update installed, rebooting ...

SW Update: Mar  8 2015, 17:47:50
***
Initializing network interface...
Connecting to network...
Ethernet connected as   192.168.1.119
Connected at 100 Mb/s
Committer:
WiredHome
Date:
Sun Mar 08 17:05:20 2015 +0000
Revision:
0:a97a04fc949f
Child:
1:04cb8d33b910
Minimized the unrelated code, to more easily focus on the SW Update test and results.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:a97a04fc949f 1 //
WiredHome 0:a97a04fc949f 2 // Software Update Test Program
WiredHome 0:a97a04fc949f 3 //
WiredHome 0:a97a04fc949f 4 // There is more here than needed purely for the SWUpdate library.
WiredHome 0:a97a04fc949f 5 //
WiredHome 0:a97a04fc949f 6 #include "mbed.h" // mbed: ver 95, rtos: 64, previously: ver 85, rtos ver 40
WiredHome 0:a97a04fc949f 7 #include "RawSerial.h" // for console i/o
WiredHome 0:a97a04fc949f 8
WiredHome 0:a97a04fc949f 9 // My custom libraries
WiredHome 0:a97a04fc949f 10 #include "HTTPClient.h" // ver 33
WiredHome 0:a97a04fc949f 11 #include "SWUpdate.h" // ver 20
WiredHome 0:a97a04fc949f 12 #include "Watchdog.h" // ver 4
WiredHome 0:a97a04fc949f 13
WiredHome 0:a97a04fc949f 14
WiredHome 0:a97a04fc949f 15 #include "EthernetInterface.h" // ver 47
WiredHome 0:a97a04fc949f 16 #include "EthStatus.h" // connection state and speed...
WiredHome 0:a97a04fc949f 17
WiredHome 0:a97a04fc949f 18 const char * PROG_INFO = "SW Update: " __DATE__ ", " __TIME__;
WiredHome 0:a97a04fc949f 19 const char * iniFile = "/local/SWUpdate.ini";
WiredHome 0:a97a04fc949f 20
WiredHome 0:a97a04fc949f 21 EthernetInterface eth;
WiredHome 0:a97a04fc949f 22 Watchdog wd;
WiredHome 0:a97a04fc949f 23
WiredHome 0:a97a04fc949f 24 RawSerial pc(USBTX, USBRX);
WiredHome 0:a97a04fc949f 25 LocalFileSystem local("local");
WiredHome 0:a97a04fc949f 26
WiredHome 0:a97a04fc949f 27 HTTPClient http;
WiredHome 0:a97a04fc949f 28
WiredHome 0:a97a04fc949f 29 extern "C" void mbed_reset();
WiredHome 0:a97a04fc949f 30
WiredHome 0:a97a04fc949f 31 void SoftwareUpdateCheck(void)
WiredHome 0:a97a04fc949f 32 {
WiredHome 0:a97a04fc949f 33 char *url = "http://192.168.1.201/mbed";
WiredHome 0:a97a04fc949f 34 char *name = "SWUp";
WiredHome 0:a97a04fc949f 35
WiredHome 0:a97a04fc949f 36 pc.printf("SoftwareUpdateCheck (%s) (%s)\r\n", url, name);
WiredHome 0:a97a04fc949f 37 SWUpdate_T su = SoftwareUpdate(url, name, DEFER_REBOOT);
WiredHome 0:a97a04fc949f 38 if (SWUP_OK == su) {
WiredHome 0:a97a04fc949f 39 pc.printf(" Update installed, rebooting ...\r\n");
WiredHome 0:a97a04fc949f 40 Thread::wait(3000);
WiredHome 0:a97a04fc949f 41 mbed_reset();
WiredHome 0:a97a04fc949f 42 } else if (SWUP_SAME_VER == su) {
WiredHome 0:a97a04fc949f 43 pc.printf(" no update available.\r\n");
WiredHome 0:a97a04fc949f 44 } else {
WiredHome 0:a97a04fc949f 45 pc.printf(" update failed %04X\r\n", su);
WiredHome 0:a97a04fc949f 46 }
WiredHome 0:a97a04fc949f 47 }
WiredHome 0:a97a04fc949f 48
WiredHome 0:a97a04fc949f 49
WiredHome 0:a97a04fc949f 50
WiredHome 0:a97a04fc949f 51 void ShowIPAddress(bool show)
WiredHome 0:a97a04fc949f 52 {
WiredHome 0:a97a04fc949f 53 char buf[16];
WiredHome 0:a97a04fc949f 54
WiredHome 0:a97a04fc949f 55 if (show)
WiredHome 0:a97a04fc949f 56 sprintf(buf, "%15s", eth.getIPAddress());
WiredHome 0:a97a04fc949f 57 else
WiredHome 0:a97a04fc949f 58 sprintf(buf, "%15s", "---.---.---.---");
WiredHome 0:a97a04fc949f 59 pc.printf("Ethernet connected as %s\r\n", buf);
WiredHome 0:a97a04fc949f 60 }
WiredHome 0:a97a04fc949f 61
WiredHome 0:a97a04fc949f 62
WiredHome 0:a97a04fc949f 63
WiredHome 0:a97a04fc949f 64 void CheckConsoleInput(void)
WiredHome 0:a97a04fc949f 65 {
WiredHome 0:a97a04fc949f 66 if (pc.readable()) {
WiredHome 0:a97a04fc949f 67 int c = pc.getc();
WiredHome 0:a97a04fc949f 68 switch (c) {
WiredHome 0:a97a04fc949f 69 case 'r':
WiredHome 0:a97a04fc949f 70 mbed_reset();
WiredHome 0:a97a04fc949f 71 break;
WiredHome 0:a97a04fc949f 72 case 's':
WiredHome 0:a97a04fc949f 73 SoftwareUpdateCheck();
WiredHome 0:a97a04fc949f 74 break;
WiredHome 0:a97a04fc949f 75 default:
WiredHome 0:a97a04fc949f 76 pc.printf("unknown command '%c'\r\n", c);
WiredHome 0:a97a04fc949f 77 break;
WiredHome 0:a97a04fc949f 78 }
WiredHome 0:a97a04fc949f 79 }
WiredHome 0:a97a04fc949f 80 }
WiredHome 0:a97a04fc949f 81
WiredHome 0:a97a04fc949f 82 bool NetworkIsConnected(void)
WiredHome 0:a97a04fc949f 83 {
WiredHome 0:a97a04fc949f 84 return get_link_status();
WiredHome 0:a97a04fc949f 85 }
WiredHome 0:a97a04fc949f 86
WiredHome 0:a97a04fc949f 87
WiredHome 0:a97a04fc949f 88 int main()
WiredHome 0:a97a04fc949f 89 {
WiredHome 0:a97a04fc949f 90 pc.baud(460800);
WiredHome 0:a97a04fc949f 91 pc.printf("\r\n%s\r\n", PROG_INFO);
WiredHome 0:a97a04fc949f 92
WiredHome 0:a97a04fc949f 93 if (wd.WatchdogCausedReset()) {
WiredHome 0:a97a04fc949f 94 pc.printf("**** Watchdog Event caused reset ****\r\n");
WiredHome 0:a97a04fc949f 95 }
WiredHome 0:a97a04fc949f 96 wd.Configure(30.0); // nothing should take more than 30 s we hope.
WiredHome 0:a97a04fc949f 97
WiredHome 0:a97a04fc949f 98 pc.printf("***\r\n");
WiredHome 0:a97a04fc949f 99 pc.printf("Initializing network interface...\r\n");
WiredHome 0:a97a04fc949f 100 if (0 == eth.init()) { //Use DHCP
WiredHome 0:a97a04fc949f 101 do {
WiredHome 0:a97a04fc949f 102 pc.printf("Connecting to network...\r\n");
WiredHome 0:a97a04fc949f 103 if (0 == eth.connect()) {
WiredHome 0:a97a04fc949f 104 ShowIPAddress(true);
WiredHome 0:a97a04fc949f 105 int speed = get_connection_speed();
WiredHome 0:a97a04fc949f 106 pc.printf("Connected at %d Mb/s\r\n", speed);
WiredHome 0:a97a04fc949f 107 while (NetworkIsConnected()) {
WiredHome 0:a97a04fc949f 108 Thread::wait(500);
WiredHome 0:a97a04fc949f 109 CheckConsoleInput();
WiredHome 0:a97a04fc949f 110 wd.Service();
WiredHome 0:a97a04fc949f 111 }
WiredHome 0:a97a04fc949f 112 pc.printf("lost connection.\r\n");
WiredHome 0:a97a04fc949f 113 ShowIPAddress(false);
WiredHome 0:a97a04fc949f 114 eth.disconnect();
WiredHome 0:a97a04fc949f 115 }
WiredHome 0:a97a04fc949f 116 else {
WiredHome 0:a97a04fc949f 117 pc.printf(" ... failed to connect.\r\n");
WiredHome 0:a97a04fc949f 118 }
WiredHome 0:a97a04fc949f 119 CheckConsoleInput();
WiredHome 0:a97a04fc949f 120 }
WiredHome 0:a97a04fc949f 121 while (1);
WiredHome 0:a97a04fc949f 122 }
WiredHome 0:a97a04fc949f 123 else {
WiredHome 0:a97a04fc949f 124 pc.printf(" ... failed to initialize, rebooting...\r\n");
WiredHome 0:a97a04fc949f 125 mbed_reset();
WiredHome 0:a97a04fc949f 126 }
WiredHome 0:a97a04fc949f 127 }