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.
main.cpp
00001 #include "mbed.h" 00002 #include "stdint.h" 00003 #include "DirHandle.h" 00004 #include "SDHCFileSystem.h" 00005 00006 SDFileSystem sd(p5, p6, p7, p8, "SDCard"); // mosi, miso, sclk, cs 00007 00008 DigitalOut led1(LED1); 00009 DigitalOut led2(LED2); 00010 DigitalOut led3(LED3); 00011 DigitalOut led4(LED4); 00012 Serial pc(USBTX, USBRX); 00013 00014 // cd 00015 // cat 00016 // ls 00017 00018 char cwd[64]; 00019 char arg[64]; 00020 char buf[128]; 00021 bool debug=false; 00022 00023 void shell(void); 00024 char *split(char *s, char *t, int max, char delim); 00025 void termInput(char *cmd); 00026 void resolveDirectory(char *newpath, char *path); 00027 void splitName(char *path, char *dirname, char *basename); 00028 void ls(char *path); 00029 void cd(char *path); 00030 void pwd(void); 00031 void touch(char *path); 00032 void head(char *path); 00033 void cat(char *path); 00034 00035 int main() 00036 { 00037 pc.baud(115200); 00038 00039 shell(); 00040 00041 while (1) { 00042 led1 = !led1; 00043 wait_ms(250); 00044 led2 = !led2; 00045 wait_ms(250); 00046 led3 = !led3; 00047 wait_ms(250); 00048 led4 = !led4; 00049 wait_ms(250); 00050 } 00051 } 00052 00053 void shell() { 00054 FILE *fp; 00055 char newpath[64], *arg, cmd[64], cmdline[64]; 00056 bool done=false; 00057 00058 //Logger.SelectCRCMode(1); 00059 00060 //pc.printf("Formatting...\n"); 00061 //int i = Logger.format(32); 00062 //pc.printf("format result: %d\n", i); 00063 00064 if ((fp = fopen("/SDCard/message.txt", "w")) != NULL) { 00065 for (int i=0; i < 20; i++) 00066 fprintf(fp, "Hello, World!\n"); 00067 fclose(fp); 00068 //pc.printf("created!\n"); 00069 } else { 00070 pc.printf("Error creating file\n"); 00071 } 00072 pc.printf("\n"); 00073 00074 strcpy(cwd, "/SDCard"); 00075 00076 while (!done) { 00077 termInput(cmdline); 00078 arg = split(cmd, cmdline, 64, ' '); 00079 resolveDirectory(newpath, arg); 00080 00081 if (debug) pc.printf("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", cmdline, cmd, arg, newpath); 00082 00083 if (!strcmp(cmd, "ls")) { 00084 ls(newpath); 00085 } else if (!strcmp(cmd, "cd")) { 00086 cd(newpath); 00087 } else if (!strcmp(cmd, "pwd")) { 00088 pwd(); 00089 } else if (!strcmp(cmd, "head")) { 00090 head(newpath); 00091 } else if (!strcmp(cmd, "cat")) { 00092 cat(newpath); 00093 } else if (!strcmp(cmd, "mkdir")) { 00094 mkdir(newpath, 1023); 00095 } else if (!strcmp(cmd, "debug")) { 00096 debug = !debug; 00097 } else if (!strcmp(cmd, "touch")) { 00098 touch(newpath); 00099 } else if (!strcmp(cmd, "rm")) { 00100 remove(newpath); 00101 } else if (!strcmp(cmd, "exit")) { 00102 done = true; 00103 } else { 00104 pc.printf("%s: command not found\n", cmd); 00105 } 00106 } 00107 00108 /* 00109 pc.printf("Printing splitName()\n"); 00110 splitName("/SDCard/testdir", dirname, basename); 00111 pc.printf("%s %s\n", dirname, basename); 00112 00113 pc.printf("Printing resolveDirectory()\n"); 00114 resolveDirectory(newpath, "test"); 00115 pc.printf("%s\n", newpath); 00116 */ 00117 00118 // remove("/SDCard/testdir/TEST.txt"); 00119 00120 /*int test = rename("/SDCard/message.txt", "/SDCard/message2.txt"); 00121 fp = fopen("/SDCard/message.txt", "a"); 00122 fprintf(fp, " Result = %d", test); 00123 fclose(fp);*/ 00124 00125 pc.printf ("exiting shell\n"); 00126 00127 return; 00128 } 00129 00130 // copy t to s until delimiter is reached 00131 // return location of delimiter+1 in t 00132 char *split(char *s, char *t, int max, char delim) 00133 { 00134 int i = 0; 00135 char *v; 00136 00137 if (s == 0 || t == 0) 00138 return 0; 00139 00140 while (*t != 0 && *t != delim && i < max) { 00141 *s++ = *t++; 00142 i++; 00143 } 00144 *s = 0; 00145 00146 if (*t == '\0') 00147 v = s; 00148 else 00149 v = t+1; 00150 00151 return v; 00152 } 00153 00154 00155 /** termInput 00156 * 00157 */ 00158 void termInput(char *cmd) { 00159 int i=0; 00160 char c; 00161 bool done = false; 00162 00163 memset(cmd, 0, 64); 00164 00165 pc.printf("# ", cwd); 00166 do { 00167 cmd[i] = 0; 00168 c = pc.getc(); 00169 if (c == '\r') { // if return is hit, we're done, don't add \r to cmd 00170 done = true; 00171 } else if (i < 64-1) { 00172 if (c == 0x7f) { // backspace 00173 if (i > 0) { // if we're at the beginning, do nothing 00174 i--; 00175 pc.printf("\b \b"); 00176 } 00177 } else { 00178 pc.printf("%c", c); 00179 cmd[i++] = c; 00180 } 00181 } 00182 } while (!done); 00183 pc.printf("\n"); 00184 } 00185 00186 /** resolveDirectory 00187 * resolve the directory path provided, given the cwd 00188 */ 00189 void resolveDirectory(char *newpath, char *path) { 00190 char basename[64], dirname[64]; 00191 00192 /** absolute path */ 00193 if (path[0] == '/') { 00194 strcpy(newpath, path); 00195 } 00196 /** relative path */ 00197 else { 00198 strcpy(newpath, cwd); 00199 if (path[0] != 0) { 00200 if (newpath[strlen(newpath)-1] != '/') 00201 strcat(newpath, "/"); 00202 strcat(newpath, path); 00203 } 00204 /** Resolve .. references */ 00205 splitName(newpath, dirname, basename); 00206 if (!strcmp(basename, "..")) { 00207 splitName(dirname, newpath, basename); 00208 } 00209 } 00210 } 00211 00212 /** splitName 00213 * split the path into a dirname and a basename 00214 */ 00215 void splitName(char *path, char *dirname, char *basename) { 00216 int sep; 00217 00218 sep = 0; 00219 if (debug) pc.printf("%d\n", strlen(path)); 00220 for (int i=strlen(path)-1; i >= 0; i--) { 00221 if (debug) pc.printf("- %c\n", path[i]); 00222 sep = i; 00223 if (path[i] == '/') break; 00224 } 00225 for (int j=0; j < sep; j++) { 00226 if (debug) pc.printf("> %c\n", path[j]); 00227 dirname[j] = path[j]; 00228 dirname[j+1] = 0; 00229 } 00230 for (int k=sep+1; k < strlen(path); k++) { 00231 if (debug) pc.printf("* %c\n", path[k]); 00232 basename[k-(sep+1)] = path[k]; 00233 basename[k-sep] = 0; 00234 } 00235 if (debug) pc.printf("d:<%s> b:<%s>\n", dirname, basename); 00236 } 00237 00238 /** ls 00239 * lists files in the current working directory 00240 */ 00241 void ls(char *path) { 00242 if (debug) pc.printf("%s\n", cwd); 00243 DIR *d; 00244 struct dirent *p; 00245 00246 if ((d = opendir(path)) != NULL) { 00247 while ((p = readdir(d)) != NULL) { 00248 pc.printf(" %s\n", p->d_name); 00249 } 00250 closedir(d); 00251 } else { 00252 pc.printf("%s: No such directory\n", path); 00253 } 00254 } 00255 00256 /** cd 00257 * changes current working directory 00258 */ 00259 void cd(char *path) { 00260 strcpy(cwd, path); 00261 } 00262 00263 /** pwd 00264 * print current working directory 00265 */ 00266 void pwd() { 00267 pc.printf("%s\n", cwd); 00268 } 00269 00270 /** touch 00271 * create an empty file 00272 */ 00273 void touch(char *path) { 00274 FILE *fp; 00275 if ((fp = fopen(path, "w")) != NULL) { 00276 fclose(fp); 00277 } else { 00278 pc.printf("%s: No such file\n", path); 00279 } 00280 } 00281 00282 /** head 00283 * print the first 10 lines of a file 00284 */ 00285 void head(char *path) { 00286 FILE *fp; 00287 char line = 0; 00288 00289 if ((fp = fopen(path, "r")) != NULL) { 00290 while (!feof(fp) && line++ < 10) { 00291 fgets(buf, 128, fp); 00292 pc.printf("%s", buf); 00293 } 00294 fclose(fp); 00295 } else { 00296 pc.printf("%s: No such file\n", path); 00297 } 00298 } 00299 00300 /** cat 00301 * display the content of a file 00302 */ 00303 void cat(char *path) { 00304 FILE *fp; 00305 00306 if ((fp = fopen(path, "r")) != NULL) { 00307 while (!feof(fp)) { 00308 fgets(buf, 128, fp); 00309 pc.printf("%s", buf); 00310 } 00311 fclose(fp); 00312 } else { 00313 pc.printf("%s: No such file\n", path); 00314 } 00315 }
Generated on Wed Jul 13 2022 08:04:37 by
1.7.2