Run multiple binaries on your mbed.

Dependencies:   mbed

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
+