Demonstration of a very simple unix-like shell. Based on integrating both Klaus Bu\'s SDHCFileSystem and the FATFileSystem library out of Thomas Hamilton\'s SDCard program. Result: you get high capacity + a plethora of filesystem functions.
Diff: main.cpp
- Revision:
- 0:792bddcf799d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Oct 11 15:13:42 2011 +0000 @@ -0,0 +1,315 @@ +#include "mbed.h" +#include "stdint.h" +#include "DirHandle.h" +#include "SDHCFileSystem.h" + +SDFileSystem sd(p5, p6, p7, p8, "SDCard"); // mosi, miso, sclk, cs + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +Serial pc(USBTX, USBRX); + +// cd +// cat +// ls + +char cwd[64]; +char arg[64]; +char buf[128]; +bool debug=false; + +void shell(void); +char *split(char *s, char *t, int max, char delim); +void termInput(char *cmd); +void resolveDirectory(char *newpath, char *path); +void splitName(char *path, char *dirname, char *basename); +void ls(char *path); +void cd(char *path); +void pwd(void); +void touch(char *path); +void head(char *path); +void cat(char *path); + +int main() +{ + pc.baud(115200); + + shell(); + + while (1) { + led1 = !led1; + wait_ms(250); + led2 = !led2; + wait_ms(250); + led3 = !led3; + wait_ms(250); + led4 = !led4; + wait_ms(250); + } +} + +void shell() { + FILE *fp; + char newpath[64], *arg, cmd[64], cmdline[64]; + bool done=false; + + //Logger.SelectCRCMode(1); + + //pc.printf("Formatting...\n"); + //int i = Logger.format(32); + //pc.printf("format result: %d\n", i); + + if ((fp = fopen("/SDCard/message.txt", "w")) != NULL) { + for (int i=0; i < 20; i++) + fprintf(fp, "Hello, World!\n"); + fclose(fp); + //pc.printf("created!\n"); + } else { + pc.printf("Error creating file\n"); + } + pc.printf("\n"); + + strcpy(cwd, "/SDCard"); + + while (!done) { + termInput(cmdline); + arg = split(cmd, cmdline, 64, ' '); + resolveDirectory(newpath, arg); + + if (debug) pc.printf("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", cmdline, cmd, arg, newpath); + + if (!strcmp(cmd, "ls")) { + ls(newpath); + } else if (!strcmp(cmd, "cd")) { + cd(newpath); + } else if (!strcmp(cmd, "pwd")) { + pwd(); + } else if (!strcmp(cmd, "head")) { + head(newpath); + } else if (!strcmp(cmd, "cat")) { + cat(newpath); + } else if (!strcmp(cmd, "mkdir")) { + mkdir(newpath, 1023); + } else if (!strcmp(cmd, "debug")) { + debug = !debug; + } else if (!strcmp(cmd, "touch")) { + touch(newpath); + } else if (!strcmp(cmd, "rm")) { + remove(newpath); + } else if (!strcmp(cmd, "exit")) { + done = true; + } else { + pc.printf("%s: command not found\n", cmd); + } + } + +/* + pc.printf("Printing splitName()\n"); + splitName("/SDCard/testdir", dirname, basename); + pc.printf("%s %s\n", dirname, basename); + + pc.printf("Printing resolveDirectory()\n"); + resolveDirectory(newpath, "test"); + pc.printf("%s\n", newpath); +*/ + +// remove("/SDCard/testdir/TEST.txt"); + + /*int test = rename("/SDCard/message.txt", "/SDCard/message2.txt"); + fp = fopen("/SDCard/message.txt", "a"); + fprintf(fp, " Result = %d", test); + fclose(fp);*/ + + pc.printf ("exiting shell\n"); + + return; +} + +// copy t to s until delimiter is reached +// return location of delimiter+1 in t +char *split(char *s, char *t, int max, char delim) +{ + int i = 0; + char *v; + + if (s == 0 || t == 0) + return 0; + + while (*t != 0 && *t != delim && i < max) { + *s++ = *t++; + i++; + } + *s = 0; + + if (*t == '\0') + v = s; + else + v = t+1; + + return v; +} + + +/** termInput + * + */ +void termInput(char *cmd) { + int i=0; + char c; + bool done = false; + + memset(cmd, 0, 64); + + pc.printf("# ", cwd); + do { + cmd[i] = 0; + c = pc.getc(); + if (c == '\r') { // if return is hit, we're done, don't add \r to cmd + done = true; + } else if (i < 64-1) { + if (c == 0x7f) { // backspace + if (i > 0) { // if we're at the beginning, do nothing + i--; + pc.printf("\b \b"); + } + } else { + pc.printf("%c", c); + cmd[i++] = c; + } + } + } while (!done); + pc.printf("\n"); +} + +/** resolveDirectory + * resolve the directory path provided, given the cwd + */ +void resolveDirectory(char *newpath, char *path) { + char basename[64], dirname[64]; + + /** absolute path */ + if (path[0] == '/') { + strcpy(newpath, path); + } + /** relative path */ + else { + strcpy(newpath, cwd); + if (path[0] != 0) { + if (newpath[strlen(newpath)-1] != '/') + strcat(newpath, "/"); + strcat(newpath, path); + } + /** Resolve .. references */ + splitName(newpath, dirname, basename); + if (!strcmp(basename, "..")) { + splitName(dirname, newpath, basename); + } + } +} + +/** splitName + * split the path into a dirname and a basename + */ +void splitName(char *path, char *dirname, char *basename) { + int sep; + + sep = 0; + if (debug) pc.printf("%d\n", strlen(path)); + for (int i=strlen(path)-1; i >= 0; i--) { + if (debug) pc.printf("- %c\n", path[i]); + sep = i; + if (path[i] == '/') break; + } + for (int j=0; j < sep; j++) { + if (debug) pc.printf("> %c\n", path[j]); + dirname[j] = path[j]; + dirname[j+1] = 0; + } + for (int k=sep+1; k < strlen(path); k++) { + if (debug) pc.printf("* %c\n", path[k]); + basename[k-(sep+1)] = path[k]; + basename[k-sep] = 0; + } + if (debug) pc.printf("d:<%s> b:<%s>\n", dirname, basename); +} + +/** ls + * lists files in the current working directory + */ +void ls(char *path) { + if (debug) pc.printf("%s\n", cwd); + DIR *d; + struct dirent *p; + + if ((d = opendir(path)) != NULL) { + while ((p = readdir(d)) != NULL) { + pc.printf(" %s\n", p->d_name); + } + closedir(d); + } else { + pc.printf("%s: No such directory\n", path); + } +} + +/** cd + * changes current working directory + */ +void cd(char *path) { + strcpy(cwd, path); +} + +/** pwd + * print current working directory + */ +void pwd() { + pc.printf("%s\n", cwd); +} + +/** touch + * create an empty file + */ +void touch(char *path) { + FILE *fp; + if ((fp = fopen(path, "w")) != NULL) { + fclose(fp); + } else { + pc.printf("%s: No such file\n", path); + } +} + +/** head + * print the first 10 lines of a file + */ +void head(char *path) { + FILE *fp; + char line = 0; + + if ((fp = fopen(path, "r")) != NULL) { + while (!feof(fp) && line++ < 10) { + fgets(buf, 128, fp); + pc.printf("%s", buf); + } + fclose(fp); + } else { + pc.printf("%s: No such file\n", path); + } +} + +/** cat + * display the content of a file + */ +void cat(char *path) { + FILE *fp; + + if ((fp = fopen(path, "r")) != NULL) { + while (!feof(fp)) { + fgets(buf, 128, fp); + pc.printf("%s", buf); + } + fclose(fp); + } else { + pc.printf("%s: No such file\n", path); + } +}