A UNIX emulation shell to access the underlying SDCard FileSystem through a terminal interface
Information
Dependencies not included with library:
Information
SDShell does not change the com baudrate. Access is made using the baud as initialized by the Serial object when passed into the SDShell object
Example
#include "mbed.h" #include "SDFileSystem.h" #include "SDShell.h" Serial com(USBTX, USBRX); SDFileSystem sd(p11, p12, p13, p14, "sd"); SDShell emulate; int main() { emulate.init(); emulate.shell(com, sd, "/sd"); }
Diff: SDShell.cpp
- Revision:
- 2:b3107e463974
- Parent:
- 1:514f321aa528
- Child:
- 4:6ff0a3d92778
--- a/SDShell.cpp Sat Apr 27 16:08:39 2013 +0000 +++ b/SDShell.cpp Sat Apr 27 23:09:06 2013 +0000 @@ -13,10 +13,21 @@ void SDShell::init(void) { // add known commands to a linked list + _cmds.attachMsg("ls" , this, &SDShell::ls); + _cmds.attachMsg("cd" , this, &SDShell::cd); + _cmds.attachMsg("pwd" , this, &SDShell::pwd); + _cmds.attachMsg("head" , this, &SDShell::head); + _cmds.attachMsg("cat" , this, &SDShell::cat); + _cmds.attachMsg("mkdir", this, &SDShell::create); + _cmds.attachMsg("touch", this, &SDShell::touch); + _cmds.attachMsg("rm" , this, &SDShell::rm); + _cmds.attachMsg("exit" , this, &SDShell::exit); + _cmds.attachMsg("debug", this, &SDShell::debug); + return; } -void SDShell::shell(Serial &com, SDFileSystem &storage, char *cwd) +void SDShell::shell(Serial &com, SDFileSystem &storage, char const *cwd) { uint32_t done = 0; @@ -25,64 +36,41 @@ _storage = &storage; // put the current working directory to the root of the card - should be pulled in I think - strcpy(_cwd, "/sd"); + strcpy(_cwd, cwd); while(0 == done) { // gather input from the Serial object shellInput(); // break up the command line arguemnt - _arg = split(_cmd, _cmd_line, 64, ' '); + _arg = split(_cmd, _cmdline, 64, ' '); // look at the arg and get paths and files separated if present - resolveDirectory(_new_path, _arg); + resolveDirectory(_newpath, _arg); + // print parsed members if we're debugging if(_debug) { - LOG("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", _cmd_line, _cmd, _arg, _new_path); + LOG("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", _cmdline, _cmd, _arg, _newpath); } - - if (match(_cmd, "ls")) - { - ls(_new_path, _com); - } - else if (match(_cmd, "cd")) - { - cd(_new_path); - } - else if (match(_cmd, "pwd")) - { - pwd(_com); - } - else if (match(_cmd, "head")) - { - head(_new_path, _com); - } - else if (match(_cmd, "cat")) + // now service known messages + char* result = _cmds.serviceMessage(_cmd); + // look at the result > 0 means we found somehting + if(result == (char *)EXIT) { - cat(_new_path, _com); - } - else if (match(_cmd, "mkdir")) - { - mkdir(_new_path, 1023); - } - else if (match(_cmd, "debug")) - { - _debug = !_debug; + done = 1; // force an exit } - else if (match(_cmd, "touch")) - { - touch(_new_path, _com); - } - else if (match(_cmd, "rm")) + else if (result == (char *)UNKNOWN) // didnt know what that was { - remove(_new_path); - } - else if (match(_cmd, "exit")) - { - done = true; + uint32_t cnt = 1; + LOG("Unknown Message from Terminal: Options are\n"); + do + { + result = _cmds.messageLookup(cnt++); + _com->printf(" %s\n", result); + } while(result != NULL); } else { - _com->printf("%s: command not found\n", _cmd); + // that should have done something } } } @@ -93,33 +81,33 @@ char c; uint32_t done = 0; // clear the last command - memset(_cmd, 0, 64); +// memset(_cmdline, 0, SHELL_BUF_SIZE); _com->printf("# ", _cwd); do { - _cmd[i] = 0; - c = _com->getc(); - if (c == '\r') + _cmdline[i] = 0; // clearing the next loc before using it is faster than memset + c = _com->getc(); // get a char + if (c == '\r') // process on "enter" { done = 1; } - else if (i < SHELL_BUF_MASK) + else if (i < SHELL_BUF_MASK) // once full the user can only press enter { - if (c == 0x7f) - { // backspace - if (i > 0) - { // if we're at the beginning, do nothing + if (c == 0x7f) // backspace + { + if (i > 0) // if we're at the beginning, do nothing + { i--; _com->printf("\b \b"); } } - else + else // valid keystrokes get stored and echo'd { _com->putc(c); - _cmd[i++] = c; + _cmdline[i++] = c; } } - } while (0 == done); + } while(0 == done); _com->printf("\n"); } @@ -130,19 +118,19 @@ char *v; // make sure pointers are valid (could validate RAM but that should be the caller responsibility) - if ((src == 0) || (dst == 0)) + if ((dst == 0) || (src == 0)) { return 0; } - // break up the string + // break up the string until delim is found while((*src != 0) && (*src != delim) && (i < max)) { *(dst++) = *(src++); i++; } - - *src = 0; - v = (*dst == '\0') ? src : (dst+1); + // return what comes after the delimiter - dst has before the delimiter + *dst = 0; + v = (*src == '\0') ? dst : (src+1); return v; } @@ -184,14 +172,15 @@ void SDShell::splitName(char *path, char *dirname, char *basename) { int sep = 0; - + // print the original path if (_debug) { LOG("%d\n", strlen(path)); } + // find the directory backslash location in the path for (int i=strlen(path)-1; i >= 0; i--) { - if (_debug) + if (_debug) // print what we found { LOG("- %c\n", path[i]); } @@ -201,99 +190,154 @@ break; } } - for (int j=0; j < sep; j++) + // extract the directory + for (int i=0; i < sep; i++) { - if (_debug) + if (_debug) // print what we found { - LOG("> %c\n", path[j]); + LOG("> %c\n", path[i]); } - dirname[j] = path[j]; - dirname[j+1] = 0; + dirname[i] = path[i]; + dirname[i+1] = 0; } - for (int k=sep+1; k < strlen(path); k++) + // and then split the file from directory + for (int i=sep+1; i < strlen(path); i++) { - if (_debug) + if (_debug) // print what we found { - LOG("* %c\n", path[k]); + LOG("* %c\n", path[i]); } - basename[k-(sep+1)] = path[k]; - basename[k-sep] = 0; + basename[i-(sep+1)] = path[i]; + basename[i-sep] = 0; } - if (_debug) + if (_debug) // print the the split { LOG("d:<%s> b:<%s>\n", dirname, basename); } } -uint32_t SDShell::match(char *arg1, char *arg2) +char *SDShell::ls(char *cmd) { - return (0 == strcmp(arg1, arg2)) ? 1 : 0; + if (_debug) + { + LOG("%s\n", _cwd); + } + + DIR *d = opendir(_newpath); + if (NULL != d) + { + struct dirent *p; + while ((p = readdir(d)) != NULL) + { + _com->printf(" %s\n", p->d_name); + } + closedir(d); + } + else + { + _com->printf("%s: No such directory\n", _newpath); + } + + return (char *)OK; } -void SDShell::ls(char *path, Serial *pc) +char *SDShell::cd(char *cmd) { - if (_debug) pc->printf("%s\n", _cwd); - DIR *d; - struct dirent *p; + strcpy(_cwd, _newpath); + + return (char *)OK; +} - 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); - } +char *SDShell::pwd(char *path) +{ + _com->printf("%s\n", _cwd); + + return (char *)OK; } -void SDShell::cd(char *path) +char *SDShell::head(char *cmd) { - strcpy(_cwd, path); -} - -void SDShell::pwd(Serial *pc) -{ - pc->printf("%s\n", _cwd); + FILE *fp = fopen(_newpath, "r"); + if (fp != NULL) + { + uint32_t line = 0; + while ((0 == feof(fp)) && ((line++) < 10)) + { + fgets(_buf, 512, fp); + _com->printf("%s", _buf); + } + fclose(fp); + } + else + { + _com->printf("%s: No such file\n", _newpath); + } + + return (char *)OK; } -void SDShell::head(char *path, Serial *pc) +char *SDShell::cat(char *cmd) { - FILE *fp; - char line = 0; - - if ((fp = fopen(path, "r")) != NULL) { - while (!feof(fp) && line++ < 10) { - fgets(_buf, 128, fp); - pc->printf("%s", _buf); + FILE *fp= fopen(_newpath, "r"); + if (fp != NULL) + { + while (!feof(fp)) + { + fread(_buf, 1, 512, fp); + _com->printf("%s", _buf); } fclose(fp); - } else { - pc->printf("%s: No such file\n", path); } + else + { + _com->printf("%s: No such file\n", _newpath); + } + + return (char *)OK; } -void SDShell::cat(char *path, Serial *pc) +char *SDShell::touch(char *cmd) { - FILE *fp; + FILE *fp = fopen(_newpath, "w"); + if (fp != NULL) + { + _com->printf("%s: File created\n", _newpath); + fclose(fp); + } + else + { + _com->printf("%s: No such file\n", _newpath); + } + + return (char *)OK; +} - 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); - } +char *SDShell::create(char *cmd) +{ + mkdir(_newpath, 1023); + + return (char *)OK; } -void SDShell::touch(char *path, Serial *pc) +char *SDShell::rm(char *cmd) { - FILE *fp; - if ((fp = fopen(path, "w")) != NULL) { - fclose(fp); - } else { - pc->printf("%s: No such file\n", path); - } + remove(_newpath); + + return (char *)OK; } +char *SDShell::exit(char *cmd) +{ + return (char *)EXIT; +} + +char *SDShell::debug(char *cmd) +{ + _debug = !_debug; + + return (char *)OK; +} + + + +