Run multiple binaries on your mbed.

Dependencies:   mbed

Committer:
paulg
Date:
Wed May 29 20:06:47 2013 +0000
Revision:
0:4ea2252690b9
Child:
1:68f8899ed1ea
Demo of how to run multiple binaries on your mbed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
paulg 0:4ea2252690b9 1 /******************************************************************************
paulg 0:4ea2252690b9 2 * File: main.cpp
paulg 0:4ea2252690b9 3 * Author: Paul Griffith
paulg 0:4ea2252690b9 4 * Created: 27 May 2013
paulg 0:4ea2252690b9 5 * Last Edit: see below
paulg 0:4ea2252690b9 6 * Version: see below
paulg 0:4ea2252690b9 7 *
paulg 0:4ea2252690b9 8 * Description:
paulg 0:4ea2252690b9 9 * Test program to demonstrate application switching.
paulg 0:4ea2252690b9 10
paulg 0:4ea2252690b9 11 * This program loads and runs one of several different binaries.
paulg 0:4ea2252690b9 12 * The binaries are all present on the local filesystem, but are renamed to
paulg 0:4ea2252690b9 13 * app1.mbd, app2.mbd and so on. The filenames must conform to the local
paulg 0:4ea2252690b9 14 * filesystem's 8+3 filename rule and have an extension other then .bin.
paulg 0:4ea2252690b9 15 * This ensures that the files can be accessed by the local filesystem library
paulg 0:4ea2252690b9 16 * and that the interface chip does not act upon the binaries.
paulg 0:4ea2252690b9 17 * Another requirement is that all other .bin files must be deleted from the
paulg 0:4ea2252690b9 18 * local filesystem. This is necessary because downloaded files will always
paulg 0:4ea2252690b9 19 * have more recent timestamps than ones created by the local filesystem.
paulg 0:4ea2252690b9 20 * To switch applications, the current .bin file is deleted, the chosen app
paulg 0:4ea2252690b9 21 * file is copied to a .bin and the nR pin is driven low. The interface chip
paulg 0:4ea2252690b9 22 * then loads the .bin file into mbed's Flash.
paulg 0:4ea2252690b9 23 *
paulg 0:4ea2252690b9 24 * To use this program:
paulg 0:4ea2252690b9 25 * 1. From the PC, remove all .bin files from the mbed local filesystem,
paulg 0:4ea2252690b9 26 * 2. Compile as is, download to mbed and Flash it into mbed.
paulg 0:4ea2252690b9 27 * 3. From the PC, rename the binary to app1.mbd.
paulg 0:4ea2252690b9 28 * 4. Edit the MYNAME string to app2.bin
paulg 0:4ea2252690b9 29 * 5. Save, recompile and download to mbed. Do NOT Flash into mbed.
paulg 0:4ea2252690b9 30 * 6. From the PC, rename the binary to app2.mbd.
paulg 0:4ea2252690b9 31 * 7. Edit the MYNAME string to app3.bin
paulg 0:4ea2252690b9 32 * 8. Save, recompile and download to mbed. Do NOT Flash into mbed.
paulg 0:4ea2252690b9 33 * 9. From the PC, rename the binary to app3.mbd.
paulg 0:4ea2252690b9 34 * 10 Fit a wire jumper between mbed pin 9 (rstOut) and mbed pin 4 (nR).
paulg 0:4ea2252690b9 35 * Another mbed I/O pin can be used if you change the RSTPIN definition.
paulg 0:4ea2252690b9 36 * (If you don't fit a jumper you will have to press the Reset button
paulg 0:4ea2252690b9 37 * when the Resetting mbed module... prompt appears).
paulg 0:4ea2252690b9 38 *
paulg 0:4ea2252690b9 39 * The program can now be run. It uses the virtual serial port at 9600 baud
paulg 0:4ea2252690b9 40 * and has a simple command interpreter. All commands end with <Enter>.
paulg 0:4ea2252690b9 41 * Use the 1, 2 and 3 commands to switch applications.
paulg 0:4ea2252690b9 42 *
paulg 0:4ea2252690b9 43 * Copyright (c) 2013 Paul Griffith.
paulg 0:4ea2252690b9 44 * Released under the MIT License: http://mbed.org/license/mit
paulg 0:4ea2252690b9 45 *
paulg 0:4ea2252690b9 46 * Modifications:
paulg 0:4ea2252690b9 47 * Ver Date By Details
paulg 0:4ea2252690b9 48 * 0.00 27May13 PG File created.
paulg 0:4ea2252690b9 49 * 1.00 29May13 PG Initial release.
paulg 0:4ea2252690b9 50 *
paulg 0:4ea2252690b9 51 ******************************************************************************/
paulg 0:4ea2252690b9 52
paulg 0:4ea2252690b9 53 #define VERSION "1.00"
paulg 0:4ea2252690b9 54 #define MYNAME "app1.bin" //edit to desired name before compiling & downloading
paulg 0:4ea2252690b9 55 #define RSTPIN p9
paulg 0:4ea2252690b9 56
paulg 0:4ea2252690b9 57 #include "mbed.h"
paulg 0:4ea2252690b9 58
paulg 0:4ea2252690b9 59 void printHelps(void);
paulg 0:4ea2252690b9 60 void badArgs(void);
paulg 0:4ea2252690b9 61 void nyi(void);
paulg 0:4ea2252690b9 62 void pause(void);
paulg 0:4ea2252690b9 63 void usage(void);
paulg 0:4ea2252690b9 64 int getVal();
paulg 0:4ea2252690b9 65 int exist(char *);
paulg 0:4ea2252690b9 66 int copyFile(char*, char*);
paulg 0:4ea2252690b9 67 void listDir(char*);
paulg 0:4ea2252690b9 68 int renameFile(char*, char*);
paulg 0:4ea2252690b9 69 void resetMbed(void);
paulg 0:4ea2252690b9 70
paulg 0:4ea2252690b9 71 Serial pc(USBTX, USBRX);
paulg 0:4ea2252690b9 72 LocalFileSystem local("local");
paulg 0:4ea2252690b9 73
paulg 0:4ea2252690b9 74 int main() {
paulg 0:4ea2252690b9 75 char buf[120], *cp;
paulg 0:4ea2252690b9 76 char arg0[50], arg1[50], arg2[50];
paulg 0:4ea2252690b9 77 int argc, i;
paulg 0:4ea2252690b9 78
paulg 0:4ea2252690b9 79 printf("\nApplication Switcher Demo (Version %s, %s %s)\n",
paulg 0:4ea2252690b9 80 VERSION, __DATE__, __TIME__);
paulg 0:4ea2252690b9 81 printf("I am application %s\n", MYNAME);
paulg 0:4ea2252690b9 82 printf("Type ? for help\n");
paulg 0:4ea2252690b9 83
paulg 0:4ea2252690b9 84 strcpy(arg1, "/local/"); //build file name
paulg 0:4ea2252690b9 85 strcpy(arg2, "/local/"); //build file name
paulg 0:4ea2252690b9 86
paulg 0:4ea2252690b9 87 while (1) {
paulg 0:4ea2252690b9 88 printf("> ");
paulg 0:4ea2252690b9 89 cp = buf;
paulg 0:4ea2252690b9 90 while ( (*cp++ = putchar(getchar())) != '\r') ; //get a line of input
paulg 0:4ea2252690b9 91 *cp = '\0'; //terminate buffer
paulg 0:4ea2252690b9 92 printf("\n");
paulg 0:4ea2252690b9 93 argc = sscanf(buf, "%s%s%s", arg0, &arg1[7], &arg2[7]); //extract cmd & args
paulg 0:4ea2252690b9 94 if (argc < 1)
paulg 0:4ea2252690b9 95 continue;
paulg 0:4ea2252690b9 96 switch (arg0[0]) {
paulg 0:4ea2252690b9 97
paulg 0:4ea2252690b9 98 case '1': //load Application app1.bin
paulg 0:4ea2252690b9 99 if (strcmp(MYNAME, "app1.bin") == 0) {
paulg 0:4ea2252690b9 100 printf("Application app1.bin is already running!\n");
paulg 0:4ea2252690b9 101 }
paulg 0:4ea2252690b9 102 else {
paulg 0:4ea2252690b9 103 sprintf(&arg1[7], MYNAME);
paulg 0:4ea2252690b9 104 remove(arg1);
paulg 0:4ea2252690b9 105 copyFile("/local/app1.mbd", "/local/app1.bin");
paulg 0:4ea2252690b9 106 resetMbed();
paulg 0:4ea2252690b9 107 }
paulg 0:4ea2252690b9 108 break;
paulg 0:4ea2252690b9 109
paulg 0:4ea2252690b9 110 case '2': //load Application app2.bin
paulg 0:4ea2252690b9 111 if (strcmp(MYNAME, "app2.bin") == 0) {
paulg 0:4ea2252690b9 112 printf("Application app2.bin is already running!\n");
paulg 0:4ea2252690b9 113 }
paulg 0:4ea2252690b9 114 else {
paulg 0:4ea2252690b9 115 sprintf(&arg1[7], MYNAME);
paulg 0:4ea2252690b9 116 remove(arg1);
paulg 0:4ea2252690b9 117 copyFile("/local/app2.mbd", "/local/app2.bin");
paulg 0:4ea2252690b9 118 resetMbed();
paulg 0:4ea2252690b9 119 }
paulg 0:4ea2252690b9 120 break;
paulg 0:4ea2252690b9 121
paulg 0:4ea2252690b9 122 case '3': //load Application app3.bin
paulg 0:4ea2252690b9 123 if (strcmp(MYNAME, "app3.bin") == 0) {
paulg 0:4ea2252690b9 124 printf("Application app3.bin is already running!\n");
paulg 0:4ea2252690b9 125 }
paulg 0:4ea2252690b9 126 else {
paulg 0:4ea2252690b9 127 sprintf(&arg1[7], MYNAME);
paulg 0:4ea2252690b9 128 remove(arg1);
paulg 0:4ea2252690b9 129 copyFile("/local/app3.mbd", "/local/app3.bin");
paulg 0:4ea2252690b9 130 resetMbed();
paulg 0:4ea2252690b9 131 }
paulg 0:4ea2252690b9 132 break;
paulg 0:4ea2252690b9 133
paulg 0:4ea2252690b9 134 case 'c': //copy file
paulg 0:4ea2252690b9 135 if (argc != 3) {
paulg 0:4ea2252690b9 136 usage();
paulg 0:4ea2252690b9 137 break;
paulg 0:4ea2252690b9 138 }
paulg 0:4ea2252690b9 139 i = copyFile(arg1, arg2);
paulg 0:4ea2252690b9 140 printf("Copy %s to %s returned %d\n", arg1, arg2, i);
paulg 0:4ea2252690b9 141 break;
paulg 0:4ea2252690b9 142
paulg 0:4ea2252690b9 143 case 'd': //delete file
paulg 0:4ea2252690b9 144 if (argc != 2) {
paulg 0:4ea2252690b9 145 usage();
paulg 0:4ea2252690b9 146 break;
paulg 0:4ea2252690b9 147 }
paulg 0:4ea2252690b9 148 if (exist(arg1) == 0)
paulg 0:4ea2252690b9 149 printf("File does not exist\n");
paulg 0:4ea2252690b9 150 else {
paulg 0:4ea2252690b9 151 remove(arg1);
paulg 0:4ea2252690b9 152 printf("File deleted\n");
paulg 0:4ea2252690b9 153 }
paulg 0:4ea2252690b9 154 break;
paulg 0:4ea2252690b9 155
paulg 0:4ea2252690b9 156 case 'e': //check if file exists
paulg 0:4ea2252690b9 157 if (argc != 2) {
paulg 0:4ea2252690b9 158 usage();
paulg 0:4ea2252690b9 159 break;
paulg 0:4ea2252690b9 160 }
paulg 0:4ea2252690b9 161 if (exist(arg1) != 0)
paulg 0:4ea2252690b9 162 printf("File exists\n");
paulg 0:4ea2252690b9 163 else
paulg 0:4ea2252690b9 164 printf("File does not exist\n");
paulg 0:4ea2252690b9 165 break;
paulg 0:4ea2252690b9 166
paulg 0:4ea2252690b9 167 case 'i': //identify self
paulg 0:4ea2252690b9 168 printf("I am application %s\n", MYNAME);
paulg 0:4ea2252690b9 169 break;
paulg 0:4ea2252690b9 170
paulg 0:4ea2252690b9 171 case 'l': //list files on local filesystem
paulg 0:4ea2252690b9 172 listDir("/local");
paulg 0:4ea2252690b9 173 break;
paulg 0:4ea2252690b9 174
paulg 0:4ea2252690b9 175 case 'r': //rename file on local filesystem
paulg 0:4ea2252690b9 176 if (argc != 3) {
paulg 0:4ea2252690b9 177 usage();
paulg 0:4ea2252690b9 178 break;
paulg 0:4ea2252690b9 179 }
paulg 0:4ea2252690b9 180 i = renameFile(arg1, arg2);
paulg 0:4ea2252690b9 181 printf("Rename %s to %s returned %d\n", arg1, arg2, i);
paulg 0:4ea2252690b9 182 break;
paulg 0:4ea2252690b9 183
paulg 0:4ea2252690b9 184 case 'x': //reset mbed module
paulg 0:4ea2252690b9 185 resetMbed();
paulg 0:4ea2252690b9 186 break;
paulg 0:4ea2252690b9 187
paulg 0:4ea2252690b9 188 case '?': //print help
paulg 0:4ea2252690b9 189 printHelps();
paulg 0:4ea2252690b9 190 break;
paulg 0:4ea2252690b9 191
paulg 0:4ea2252690b9 192 default:
paulg 0:4ea2252690b9 193 printf("?? Unknown command\n");
paulg 0:4ea2252690b9 194 break;
paulg 0:4ea2252690b9 195 }
paulg 0:4ea2252690b9 196 }
paulg 0:4ea2252690b9 197 }
paulg 0:4ea2252690b9 198
paulg 0:4ea2252690b9 199 //************************
paulg 0:4ea2252690b9 200 // Display command summary
paulg 0:4ea2252690b9 201 //************************
paulg 0:4ea2252690b9 202
paulg 0:4ea2252690b9 203 void printHelps(void) {
paulg 0:4ea2252690b9 204 printf("Command summary:\n");
paulg 0:4ea2252690b9 205 printf("1 - 3 load specified application\n");
paulg 0:4ea2252690b9 206 printf("c old new copy file on local filesystem\n");
paulg 0:4ea2252690b9 207 printf("d filename delete file on local filesystem\n");
paulg 0:4ea2252690b9 208 printf("e filename check if file exists on local filesystem\n");
paulg 0:4ea2252690b9 209 printf("i identification\n");
paulg 0:4ea2252690b9 210 printf("l list files on local filesystem\n");
paulg 0:4ea2252690b9 211 printf("r old new rename file on local filesystem\n");
paulg 0:4ea2252690b9 212 printf("x reset mbed module\n");
paulg 0:4ea2252690b9 213 }
paulg 0:4ea2252690b9 214
paulg 0:4ea2252690b9 215 //************************
paulg 0:4ea2252690b9 216 // Miscellaneous functions
paulg 0:4ea2252690b9 217 //************************
paulg 0:4ea2252690b9 218
paulg 0:4ea2252690b9 219 void badArgs(void) {
paulg 0:4ea2252690b9 220 pc.printf("?? Bad arguments\n");
paulg 0:4ea2252690b9 221 }
paulg 0:4ea2252690b9 222
paulg 0:4ea2252690b9 223 void nyi(void) {
paulg 0:4ea2252690b9 224 pc.printf("!! Not yet implemented\n");
paulg 0:4ea2252690b9 225 }
paulg 0:4ea2252690b9 226
paulg 0:4ea2252690b9 227 void pause(void)
paulg 0:4ea2252690b9 228 {
paulg 0:4ea2252690b9 229 pc.printf("Press any key to continue . . .\n");
paulg 0:4ea2252690b9 230 pc.getc();
paulg 0:4ea2252690b9 231 }
paulg 0:4ea2252690b9 232
paulg 0:4ea2252690b9 233 void usage(void) {
paulg 0:4ea2252690b9 234 printf("Invalid command usage\n");
paulg 0:4ea2252690b9 235 }
paulg 0:4ea2252690b9 236
paulg 0:4ea2252690b9 237 // Get integer value from user. Used in enter functions
paulg 0:4ea2252690b9 238
paulg 0:4ea2252690b9 239 int getVal() {
paulg 0:4ea2252690b9 240 char buf[10];
paulg 0:4ea2252690b9 241 char* cp;
paulg 0:4ea2252690b9 242 int v;
paulg 0:4ea2252690b9 243
paulg 0:4ea2252690b9 244 cp = buf;
paulg 0:4ea2252690b9 245 while ( (*cp++ = putchar(getchar())) != '\r') ;
paulg 0:4ea2252690b9 246 *cp = '\0';
paulg 0:4ea2252690b9 247 printf("\n");
paulg 0:4ea2252690b9 248 v = 0;
paulg 0:4ea2252690b9 249 sscanf(buf, "%d", &v);
paulg 0:4ea2252690b9 250 return v;
paulg 0:4ea2252690b9 251 }
paulg 0:4ea2252690b9 252
paulg 0:4ea2252690b9 253 int exist(char *name) {
paulg 0:4ea2252690b9 254 FILE *fp;
paulg 0:4ea2252690b9 255
paulg 0:4ea2252690b9 256 fp = fopen(name, "r");
paulg 0:4ea2252690b9 257 if (fp != NULL)
paulg 0:4ea2252690b9 258 fclose(fp);
paulg 0:4ea2252690b9 259 return ((fp == NULL) ? 0 : 1);
paulg 0:4ea2252690b9 260 }
paulg 0:4ea2252690b9 261
paulg 0:4ea2252690b9 262 //*******************
paulg 0:4ea2252690b9 263 // Command processing
paulg 0:4ea2252690b9 264 //*******************
paulg 0:4ea2252690b9 265
paulg 0:4ea2252690b9 266 // Copy file
paulg 0:4ea2252690b9 267
paulg 0:4ea2252690b9 268 int copyFile(char *srcfile, char *destfile)
paulg 0:4ea2252690b9 269 {
paulg 0:4ea2252690b9 270 char buf[512];
paulg 0:4ea2252690b9 271 int end, r, w;
paulg 0:4ea2252690b9 272 long length, size = 0;
paulg 0:4ea2252690b9 273 FILE *fp, *fp2;
paulg 0:4ea2252690b9 274 Timer timer;
paulg 0:4ea2252690b9 275
paulg 0:4ea2252690b9 276 fp = fopen(srcfile, "r");
paulg 0:4ea2252690b9 277 if (fp == NULL)
paulg 0:4ea2252690b9 278 {
paulg 0:4ea2252690b9 279 printf("Source file does not exist\n");
paulg 0:4ea2252690b9 280 return(-1);
paulg 0:4ea2252690b9 281 }
paulg 0:4ea2252690b9 282 if (exist(destfile) == 1)
paulg 0:4ea2252690b9 283 {
paulg 0:4ea2252690b9 284 printf("Destination file already exists\n");
paulg 0:4ea2252690b9 285 fclose(fp);
paulg 0:4ea2252690b9 286 return(-2);
paulg 0:4ea2252690b9 287 }
paulg 0:4ea2252690b9 288 fp2 = fopen(destfile, "w");
paulg 0:4ea2252690b9 289 if (fp2 == NULL)
paulg 0:4ea2252690b9 290 {
paulg 0:4ea2252690b9 291 printf("Unable to create file\n");
paulg 0:4ea2252690b9 292 fclose(fp);
paulg 0:4ea2252690b9 293 return(-3);
paulg 0:4ea2252690b9 294 }
paulg 0:4ea2252690b9 295 fseek(fp, 0L, SEEK_END);
paulg 0:4ea2252690b9 296 length = ftell(fp);
paulg 0:4ea2252690b9 297 fseek(fp, 0L, SEEK_SET);
paulg 0:4ea2252690b9 298
paulg 0:4ea2252690b9 299 printf("copy %s to %s\n", srcfile, destfile);
paulg 0:4ea2252690b9 300
paulg 0:4ea2252690b9 301 printf("file length = %ld\n", length);
paulg 0:4ea2252690b9 302 timer.start();
paulg 0:4ea2252690b9 303 while (size < length)
paulg 0:4ea2252690b9 304 {
paulg 0:4ea2252690b9 305 r = fread(buf, 1, 512, fp); //read a sector
paulg 0:4ea2252690b9 306 w = fwrite(buf, 1, r, fp2); //write a sector
paulg 0:4ea2252690b9 307 if (w != r)
paulg 0:4ea2252690b9 308 {
paulg 0:4ea2252690b9 309 printf("file write error\n");
paulg 0:4ea2252690b9 310 fclose(fp);
paulg 0:4ea2252690b9 311 fclose(fp2);
paulg 0:4ea2252690b9 312 return(-4);
paulg 0:4ea2252690b9 313 }
paulg 0:4ea2252690b9 314 if (r < 512) //reached end
paulg 0:4ea2252690b9 315 break;
paulg 0:4ea2252690b9 316 size += r;
paulg 0:4ea2252690b9 317 }
paulg 0:4ea2252690b9 318 end = timer.read_ms();
paulg 0:4ea2252690b9 319 fclose(fp);
paulg 0:4ea2252690b9 320 fclose(fp2);
paulg 0:4ea2252690b9 321 printf("%ld bytes copied in %d.%03ds\n", size, end/1000, end%1000);
paulg 0:4ea2252690b9 322 return(0);
paulg 0:4ea2252690b9 323 }
paulg 0:4ea2252690b9 324
paulg 0:4ea2252690b9 325
paulg 0:4ea2252690b9 326 // List directory
paulg 0:4ea2252690b9 327
paulg 0:4ea2252690b9 328 void listDir(char *drive) {
paulg 0:4ea2252690b9 329 DIR *d;
paulg 0:4ea2252690b9 330 struct dirent *p;
paulg 0:4ea2252690b9 331
paulg 0:4ea2252690b9 332 d = opendir(drive);
paulg 0:4ea2252690b9 333 if (d != NULL) {
paulg 0:4ea2252690b9 334 while ((p = readdir(d)) != NULL) {
paulg 0:4ea2252690b9 335 printf(" - %s\n", p->d_name);
paulg 0:4ea2252690b9 336 }
paulg 0:4ea2252690b9 337 }
paulg 0:4ea2252690b9 338 else {
paulg 0:4ea2252690b9 339 printf("Could not open directory!\n");
paulg 0:4ea2252690b9 340 }
paulg 0:4ea2252690b9 341 closedir(d);
paulg 0:4ea2252690b9 342 }
paulg 0:4ea2252690b9 343
paulg 0:4ea2252690b9 344 // Rename file
paulg 0:4ea2252690b9 345 // this does not seem to work, perhaps rename() is broken?
paulg 0:4ea2252690b9 346
paulg 0:4ea2252690b9 347 int renameFile(char* srcfile, char* destfile) {
paulg 0:4ea2252690b9 348 if (exist(srcfile) == 0)
paulg 0:4ea2252690b9 349 {
paulg 0:4ea2252690b9 350 printf("Source file does not exist\n");
paulg 0:4ea2252690b9 351 return(-2);
paulg 0:4ea2252690b9 352 }
paulg 0:4ea2252690b9 353 if (exist(destfile) == 1)
paulg 0:4ea2252690b9 354 {
paulg 0:4ea2252690b9 355 printf("Destination file already exists\n");
paulg 0:4ea2252690b9 356 return(-3);
paulg 0:4ea2252690b9 357 }
paulg 0:4ea2252690b9 358 return( rename(srcfile, destfile) );
paulg 0:4ea2252690b9 359 }
paulg 0:4ea2252690b9 360
paulg 0:4ea2252690b9 361 // Reset mbded module
paulg 0:4ea2252690b9 362 // Requires a wire jumper between an I/O pin and pin 4
paulg 0:4ea2252690b9 363
paulg 0:4ea2252690b9 364 void resetMbed(void) {
paulg 0:4ea2252690b9 365 DigitalOut rst(RSTPIN);
paulg 0:4ea2252690b9 366
paulg 0:4ea2252690b9 367 printf("Resetting mbed module...\n");
paulg 0:4ea2252690b9 368 rst = 0;
paulg 0:4ea2252690b9 369 }
paulg 0:4ea2252690b9 370
paulg 0:4ea2252690b9 371 // END of main.cpp
paulg 0:4ea2252690b9 372