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
SWUpdate.h
00001 /// @file 00002 /// Automatic Software Update via the network. 00003 /// 00004 /// Supported Platforms: mbed LPC1768. 00005 /// 00006 /// This library provides a reasonably simple interface to updating sofware 00007 /// semi-automatically via the network. It does that by querying a web server 00008 /// upon which you have placed an updated version of the embedded software 00009 /// application. Upon finding something there, it will determine if it is 00010 /// a different version than the one you current have installed and it 00011 /// will try to download the software. If that succeeds, then it can 00012 /// optionally reboot to activate the new software. 00013 /// 00014 /// @code 00015 /// +-----------+ 00016 /// | Compiler | 00017 /// +-----------+ 00018 /// V +------------------+ 00019 /// +-----------+ |Web Server | 00020 /// |myprog.bin |------------------->| /mbed/myprog.bin | 00021 /// +-----------+ +-----------| | 00022 /// V | | 00023 /// +-----------+ | | 00024 /// |perl script|---->| /mbed/myprog.txt | 00025 /// +-----------+ +------------------+ 00026 /// A 00027 /// +---------------+ # 00028 /// |mbed appliance |<====== network =========#======... 00029 /// +---------------+ 00030 /// 00031 /// mbed server 00032 /// | | 00033 /// +-- http Get(myprog.txt) -->| 00034 /// |<-- file(myprog.txt) ------+ 00035 /// | | 00036 /// |---+ | 00037 /// | v58 newer than v57 | 00038 /// |<--+ | 00039 /// | | 00040 /// +-- http Get(myprog.bin) -->| 00041 /// |<-- file(myprog.bin) ------+ 00042 /// |<-- file(myprog.bin) ------+ 00043 /// |<-- file(myprog.bin) ------+ 00044 /// | (save as myprog58.bin) | 00045 /// | | 00046 /// |---+ | 00047 /// | integrity ck ok? | 00048 /// |<--+ | 00049 /// | | 00050 /// |---+ | 00051 /// | unlink other .bin files | 00052 /// | and reboot | 00053 /// |<--+ | 00054 /// | | 00055 /// @endcode 00056 /// 00057 /// While the name shown in the examples here is "myprog", this is unimportant. 00058 /// Your application will have a name of your choosing, which you will 00059 /// use in the API. 00060 /// 00061 /// @note Your binary file name should not exceed 6 characters. This leaves 00062 /// room for a 2-digit sequence number. Since this is using the local 00063 /// file system, it does not support long filenames when accessed from 00064 /// the mbed. So, SomeLongFile23.bin becomes somefi~1.bin and is then 00065 /// erased, leaving no file. 00066 /// 00067 /// @note This was tested with firmware version 16457. Others may/not work. 00068 /// To check your version, open the mbed.htm file in a text editor, 00069 /// and look for "&firmware=16457&" 00070 /// 00071 /// Local File System Files: 00072 /// 00073 /// The files of interest on the local file system are as follows: 00074 /// 00075 /// @li myprog58.bin - The actual application binary file that is currently 00076 /// executing. In this case, this is the 58th version that 00077 /// has been installed. You can go to 99 after which you might 00078 /// want to start over. 00079 /// @li myprog.ver - A text file, maintained by this software update 00080 /// application, that was downloaded from the server with 00081 /// application version 58. 00082 /// 00083 /// If "myprog.ver" does not exist, it will assume that the server has a 00084 /// newer application, so it will be downloaded and activated (even if all 00085 /// it does is to replace the existing myprog58.bin file). 00086 /// 00087 /// Web Server Files: 00088 /// 00089 /// The files on the web server are as follows. 00090 /// 00091 /// @li myprog.bin - The latest version of the application binary file. 00092 /// Note that this file does not have any version number 00093 /// embedded into its filename as is the case on the local 00094 /// file system. 00095 /// @li myprog.txt - A corresponding text file. The root name must match 00096 /// that of the binary file. 00097 /// 00098 /// The myprog.txt file shall have 3 comma-separated numbers in it. 00099 /// version,checksum,filesize (e.g. "58,41384,107996"). 00100 /// 00101 /// @li version is a simple number. If the number is different than 00102 /// what is stored on the local file system, then the program 00103 /// will be updated (even if the server number is lower). 00104 /// This bidirectional "update" can let you downgrade. 00105 /// @li checksum is the decimal representation of a simple 16-bit checksum. 00106 /// @li filesize is the decimal representation of the size of the file. 00107 /// 00108 /// Variations: 00109 /// 00110 /// Within that single web server folder, you could have several apps - 00111 /// @li Sensor.bin, Sensor.txt 00112 /// @li SensrB.bin, SensrB.txt 00113 /// @li SensrD.bin, SensrD.txt 00114 /// 00115 /// In this example, perhaps your first version was called SensorNode, but 00116 /// with a small hardware design change, you have a new "model B" version. 00117 /// This example also assumes that you have a need to maintain two separate 00118 /// applications, one for each hardware version. 00119 /// 00120 /// Creating the Version and Integrity Check data: 00121 /// 00122 /// You can create the server "myprog.txt" file with this perl script (not 00123 /// every detail is shown, but it should be easy to figure out). 00124 /// @code 00125 /// # Read current .txt file 00126 /// open (FT, "<$txt") || die("Can't read $txt."); 00127 /// $ver = <FT>; chomp $ver; close FT; 00128 /// $ver =~ s/(\d+),.*/$1/; 00129 /// print "Current Version is {$ver}\n"; 00130 /// 00131 /// # Read the [assumed new] .bin file 00132 /// open (FB, "<$bin") || die("Can't read $bin."); 00133 /// binmode FB; 00134 /// while (sysread(FB, $c, 1)) 00135 /// { 00136 /// $cksum = ($cksum + ord($c)) & 0xFFFF; 00137 /// $byteCount++; 00138 /// } 00139 /// close FB; 00140 /// # Advance version number and write the new .txt file 00141 /// $ver++; print "$ver Checksum is $cksum over $byteCount bytes.\n"; 00142 /// open (FT, ">$txt") || die("Can't write update to $txt."); 00143 /// printf(FT "%d,%d,%d\n", $ver, $cksum,$byteCount); 00144 /// close FT; 00145 /// @endcode 00146 /// 00147 00148 #ifndef SWUPDATE_H 00149 #define SWUPDATE_H 00150 00151 #include "mbed.h" 00152 #include "HTTPClient.h" 00153 00154 // This defines the maximum string length for a fully qualified 00155 // filename. Usually, this will be pretty short 00156 // (e.g. "/local/myprog.bin"), which should be 19 max with 8.3 filename. 00157 #define SW_MAX_FQFN 20 00158 00159 // This defines the maximum string length for the url, including 00160 // the base filename of interest. 00161 #define SW_MAX_URL 150 00162 00163 /// After downloading, the user can choose what happens next. 00164 typedef enum { 00165 DEFER_REBOOT, ///< Do not reboot to activate the new firmware. 00166 AUTO_REBOOT ///< Automatically reboot to activate the new firmware. 00167 } Reboot_T; 00168 00169 /// Value return code from the SoftwareUpdate API. 00170 /// 00171 /// Various things can go wrong in the software update process. The return 00172 /// value indicates the error. 00173 /// 00174 typedef enum { 00175 SWUP_OK = 0x00, ///< Software Update succeeded as planned. 00176 SWUP_SAME_VER = 0x01, ///< Online version is the same as the installed version. 00177 SWUP_HTTP_BIN = 0x02, ///< HTTP get returned an error while trying to fetch the bin file. 00178 SWUP_OLD_STUCK = 0x03, ///< Old file could not be removed. 00179 SWUP_VER_STUCK = 0x04, ///< Old version number could not be updated. 00180 SWUP_VWRITE_FAILED = 0x05, ///< Can't open for write the version tracking file. 00181 SWUP_INTEGRITY_FAILED = 0x06, ///< Integrity check of downloaded file failed. 00182 SWUP_HTTP_VER = 0x07, ///< HTTP get returned an error while trying to fetch the version file. 00183 SWUP_NO_SPACE = 0x08, ///< No space on file system for new version. 00184 SWUP_NO_FILE = 0x09, ///< Specified file on the server does not exist 00185 } SWUpdate_T; 00186 00187 00188 /// To perform the software update, we simply give this API the web 00189 /// server URL that is hosting the embedded software. We also give it 00190 /// the "root" name of the file of interest, which permits you to 00191 /// have different applications served from the same location. 00192 /// 00193 /// Note that the root name can be a long filename, as is typically 00194 /// produced from the cloud-based build process. This name will 00195 /// be truncated to the first 6 characters when installed on the 00196 /// mbed local file system, in order to retain space for a 2-digit 00197 /// version number. 00198 /// 00199 /// One optional parameter lets you decide what happens if a new 00200 /// version is installed - automatically reboot to launch it, or 00201 /// return to the calling program which may perform a more orderly 00202 /// reboot. 00203 /// 00204 /// @code 00205 /// ... 00206 /// if (NowIsTheTimeToCheckForSoftwareUpdates()) { 00207 /// if (SWUP_OK == SoftwareUpdate("http://192.168.1.200/path/to/file", "myprog_LPC1768", DEFER_REBOOT)) { 00208 /// printf("Software updated, rebooting now...\r\n"); 00209 /// wait_ms(5000); 00210 /// mbed_reset(); 00211 /// } 00212 /// } 00213 /// ... 00214 /// @endcode 00215 /// 00216 /// @param[in] url is a pointer to a text string of the url from which to download. 00217 /// @param[in] name is the base filename of the binary file. 00218 /// @param[in] action determines whether to automatically reboot to activate the new bin. 00219 /// @return SWUpdate_T code indicating if the update succeeded, otherwise it returns a bitmask 00220 /// of failure flags. Also, note that if it succeeded, and it was set for AUTO_REBOOT 00221 /// that it will not return from this function. 00222 /// 00223 SWUpdate_T SoftwareUpdate(const char *url, const char * name, Reboot_T action = AUTO_REBOOT); 00224 00225 /// Get the HTTP transaction return code. 00226 /// 00227 /// If something goes wrong with the communications with the server, SoftwareUpdate will 00228 /// respond with an SWUP_HTTP_VER or SWUP_HTTP_BIN return value. To learn more about 00229 /// what went wrong, this API will provide the actual return code from the HTTP transaction. 00230 /// 00231 /// @returns @ref HTTPResult code from the server transaction. 00232 /// 00233 HTTPResult SoftwareUpdateGetHTTPErrorCode(void); 00234 00235 /// Get the error message from a return code 00236 /// 00237 /// @param[in] r is the result code to translate into a message 00238 /// @returns a pointer to a text string of the message 00239 /// 00240 const char * SoftwareUpdateGetHTTPErrorMsg(SWUpdate_T r); 00241 00242 /// Get the installed software version number. 00243 /// 00244 /// If the installed version has a version number, retrieve that number and return it. 00245 /// 00246 /// @param name is the base filename of the binary file. 00247 /// @returns the installed version number, or -1 if it cannot be identified. 00248 /// 00249 int GetSoftwareVersionNumber(const char * name); 00250 00251 #endif // SWUPDATE_H
Generated on Wed Jul 13 2022 03:23:45 by 1.7.2