Paul Griffith
/
AppSwitcher
Run multiple binaries on your mbed.
main.cpp
- Committer:
- paulg
- Date:
- 2013-05-29
- Revision:
- 1:68f8899ed1ea
- Parent:
- 0:4ea2252690b9
File content as of revision 1:68f8899ed1ea:
/****************************************************************************** * File: main.cpp * Author: Paul Griffith * Created: 27 May 2013 * Last Edit: see below * Version: see below * * Description: * Test program to demonstrate application switching. * This program loads and runs one of several different binaries. * The binaries are all present on the local filesystem, but are renamed to * app1.mbd, app2.mbd and so on. The filenames must conform to the local * filesystem's 8+3 filename rule and have an extension other then .bin. * This ensures that the files can be accessed by the local filesystem library * and that the interface chip does not act upon the binaries. * Another requirement is that all other .bin files must be deleted from the * local filesystem. This is necessary because downloaded files will always * have more recent timestamps than ones created by the local filesystem. * To switch applications, the current .bin file is deleted, the chosen app * file is copied to a .bin and the nR pin is driven low. The interface chip * then loads the .bin file into mbed's Flash. * * To use this program: * 1. From the PC, remove all .bin files from the mbed local filesystem, * 2. Compile as is, download to mbed and Flash it into mbed. * 3. From the PC, rename the binary to app1.mbd. * 4. Edit the MYNAME string to app2.bin * 5. Save, recompile and download to mbed. Do NOT Flash into mbed. * 6. From the PC, rename the binary to app2.mbd. * 7. Edit the MYNAME string to app3.bin * 8. Save, recompile and download to mbed. Do NOT Flash into mbed. * 9. From the PC, rename the binary to app3.mbd. * 10 Fit a wire jumper between mbed pin 9 (rstOut) and mbed pin 4 (nR). * Another mbed I/O pin can be used if you change the RSTPIN definition. * (If you don't fit a jumper you will have to press the Reset button * when the Resetting mbed module... prompt appears). * * The program can now be run. It uses the virtual serial port at 9600 baud * and has a simple command interpreter. All commands end with <Enter>. * Use the 1, 2 and 3 commands to switch applications. * * Copyright (c) 2013 Paul Griffith. * Released under the MIT License: http://mbed.org/license/mit * * Modifications: * Ver Date By Details * 0.00 27May13 PG File created. * 1.00 29May13 PG Initial release. * 1.10 29May13 PG Added X command to do a software reset. * Modified 1, 2 and 3 commands to use a software reset. This * removes the need for a wire jumper. Tested on Mbed LPC1768. * ******************************************************************************/ #define VERSION "1.10" #define MYNAME "app1.bin" //edit to desired name before compiling & downloading #define RSTPIN p9 #include "mbed.h" void printHelps(void); void badArgs(void); void nyi(void); void pause(void); void usage(void); int getVal(); int exist(char *); int copyFile(char*, char*); void listDir(char*); int renameFile(char*, char*); void resetMbed(void); void resetMbed2(void); Serial pc(USBTX, USBRX); LocalFileSystem local("local"); int main() { char buf[120], *cp; char arg0[50], arg1[50], arg2[50]; int argc, i; printf("\nApplication Switcher Demo (Version %s, %s %s)\n", VERSION, __DATE__, __TIME__); printf("I am application %s\n", MYNAME); printf("Type ? for help\n"); strcpy(arg1, "/local/"); //build file name strcpy(arg2, "/local/"); //build file name while (1) { printf("> "); cp = buf; while ( (*cp++ = putchar(getchar())) != '\r') ; //get a line of input *cp = '\0'; //terminate buffer printf("\n"); argc = sscanf(buf, "%s%s%s", arg0, &arg1[7], &arg2[7]); //extract cmd & args if (argc < 1) continue; switch (arg0[0]) { case '1': //load Application app1.bin if (strcmp(MYNAME, "app1.bin") == 0) { printf("Application app1.bin is already running!\n"); } else { sprintf(&arg1[7], MYNAME); remove(arg1); copyFile("/local/app1.mbd", "/local/app1.bin"); // resetMbed(); resetMbed2(); } break; case '2': //load Application app2.bin if (strcmp(MYNAME, "app2.bin") == 0) { printf("Application app2.bin is already running!\n"); } else { sprintf(&arg1[7], MYNAME); remove(arg1); copyFile("/local/app2.mbd", "/local/app2.bin"); // resetMbed(); resetMbed2(); } break; case '3': //load Application app3.bin if (strcmp(MYNAME, "app3.bin") == 0) { printf("Application app3.bin is already running!\n"); } else { sprintf(&arg1[7], MYNAME); remove(arg1); copyFile("/local/app3.mbd", "/local/app3.bin"); // resetMbed(); resetMbed2(); } break; case 'c': //copy file if (argc != 3) { usage(); break; } i = copyFile(arg1, arg2); printf("Copy %s to %s returned %d\n", arg1, arg2, i); break; case 'd': //delete file if (argc != 2) { usage(); break; } if (exist(arg1) == 0) printf("File does not exist\n"); else { remove(arg1); printf("File deleted\n"); } break; case 'e': //check if file exists if (argc != 2) { usage(); break; } if (exist(arg1) != 0) printf("File exists\n"); else printf("File does not exist\n"); break; case 'i': //identify self printf("I am application %s\n", MYNAME); break; case 'l': //list files on local filesystem listDir("/local"); break; case 'r': //rename file on local filesystem if (argc != 3) { usage(); break; } i = renameFile(arg1, arg2); printf("Rename %s to %s returned %d\n", arg1, arg2, i); break; case 'x': //reset mbed module resetMbed(); break; case 'X': //reset mbed module using software resetMbed2(); break; case '?': //print help printHelps(); break; default: printf("?? Unknown command\n"); break; } } } //************************ // Display command summary //************************ void printHelps(void) { printf("Command summary:\n"); printf("1 - 3 load specified application\n"); printf("c old new copy file on local filesystem\n"); printf("d filename delete file on local filesystem\n"); printf("e filename check if file exists on local filesystem\n"); printf("i identification\n"); printf("l list files on local filesystem\n"); printf("r old new rename file on local filesystem\n"); printf("x reset mbed module\n"); } //************************ // Miscellaneous functions //************************ void badArgs(void) { pc.printf("?? Bad arguments\n"); } void nyi(void) { pc.printf("!! Not yet implemented\n"); } void pause(void) { pc.printf("Press any key to continue . . .\n"); pc.getc(); } void usage(void) { printf("Invalid command usage\n"); } // Get integer value from user. Used in enter functions int getVal() { char buf[10]; char* cp; int v; cp = buf; while ( (*cp++ = putchar(getchar())) != '\r') ; *cp = '\0'; printf("\n"); v = 0; sscanf(buf, "%d", &v); return v; } int exist(char *name) { FILE *fp; fp = fopen(name, "r"); if (fp != NULL) fclose(fp); return ((fp == NULL) ? 0 : 1); } //******************* // Command processing //******************* // Copy file int copyFile(char *srcfile, char *destfile) { char buf[512]; int end, r, w; long length, size = 0; FILE *fp, *fp2; Timer timer; fp = fopen(srcfile, "r"); if (fp == NULL) { printf("Source file does not exist\n"); return(-1); } if (exist(destfile) == 1) { printf("Destination file already exists\n"); fclose(fp); return(-2); } fp2 = fopen(destfile, "w"); if (fp2 == NULL) { printf("Unable to create file\n"); fclose(fp); return(-3); } fseek(fp, 0L, SEEK_END); length = ftell(fp); fseek(fp, 0L, SEEK_SET); printf("copy %s to %s\n", srcfile, destfile); printf("file length = %ld\n", length); timer.start(); while (size < length) { r = fread(buf, 1, 512, fp); //read a sector w = fwrite(buf, 1, r, fp2); //write a sector if (w != r) { printf("file write error\n"); fclose(fp); fclose(fp2); return(-4); } if (r < 512) //reached end break; size += r; } end = timer.read_ms(); fclose(fp); fclose(fp2); printf("%ld bytes copied in %d.%03ds\n", size, end/1000, end%1000); return(0); } // List directory void listDir(char *drive) { DIR *d; struct dirent *p; d = opendir(drive); if (d != NULL) { while ((p = readdir(d)) != NULL) { printf(" - %s\n", p->d_name); } } else { printf("Could not open directory!\n"); } closedir(d); } // Rename file // this does not seem to work, perhaps rename() is broken? int renameFile(char* srcfile, char* destfile) { if (exist(srcfile) == 0) { printf("Source file does not exist\n"); return(-2); } if (exist(destfile) == 1) { printf("Destination file already exists\n"); return(-3); } return( rename(srcfile, destfile) ); } // Reset mbded module // Requires a wire jumper between an I/O pin and pin 4 void resetMbed(void) { DigitalOut rst(RSTPIN); printf("Resetting mbed module...\n"); rst = 0; } // Doing it with software - thanks to Erik Olieman for suggesting this extern "C" void mbed_reset(); void resetMbed2(void) { printf("Resetting mbed module...\n"); mbed_reset(); } // END of main.cpp