Paul Griffith
/
AppSwitcher
Run multiple binaries on your mbed.
Diff: main.cpp
- Revision:
- 0:4ea2252690b9
- Child:
- 1:68f8899ed1ea
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed May 29 20:06:47 2013 +0000 @@ -0,0 +1,372 @@ +/****************************************************************************** + * 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. + * + ******************************************************************************/ + +#define VERSION "1.00" +#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); + +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(); + } + 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(); + } + 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(); + } + 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 '?': //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; +} + +// END of main.cpp +