Code for autonomous rover for Sparkfun AVC. DataBus won 3rd in 2012 and the same code was used on Troubled Child, a 1986 Jeep Grand Wagoneer to win 1st in 2014.

Dependencies:   mbed Watchdog SDFileSystem DigoleSerialDisp

Committer:
shimniok
Date:
Mon May 27 13:26:03 2013 +0000
Revision:
0:a6a169de725f
Child:
12:5dfa1ab47838
Working version with priorities set and update time display

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shimniok 0:a6a169de725f 1 #include <stdio.h>
shimniok 0:a6a169de725f 2 #include "mbed.h"
shimniok 0:a6a169de725f 3 #include "stdint.h"
shimniok 0:a6a169de725f 4 #include "DirHandle.h"
shimniok 0:a6a169de725f 5 #include "SDHCFileSystem.h"
shimniok 0:a6a169de725f 6 #include "util.h"
shimniok 0:a6a169de725f 7 #include "Buttons.h"
shimniok 0:a6a169de725f 8
shimniok 0:a6a169de725f 9 extern SDFileSystem sd;
shimniok 0:a6a169de725f 10 extern Serial pc;
shimniok 0:a6a169de725f 11 extern Buttons keypad;
shimniok 0:a6a169de725f 12
shimniok 0:a6a169de725f 13 char cwd[64];
shimniok 0:a6a169de725f 14 char buf[128];
shimniok 0:a6a169de725f 15 bool debug=false;
shimniok 0:a6a169de725f 16
shimniok 0:a6a169de725f 17 void shell(void);
shimniok 0:a6a169de725f 18 void termInput(char *cmd);
shimniok 0:a6a169de725f 19 void resolveDirectory(char *newpath, char *path);
shimniok 0:a6a169de725f 20 void splitName(char *path, char *dirname, char *basename);
shimniok 0:a6a169de725f 21 void ls(char *path);
shimniok 0:a6a169de725f 22 void cd(char *path);
shimniok 0:a6a169de725f 23 void pwd(void);
shimniok 0:a6a169de725f 24 void touch(char *path);
shimniok 0:a6a169de725f 25 void head(char *path);
shimniok 0:a6a169de725f 26 void cat(char *path);
shimniok 0:a6a169de725f 27 void send(char *path);
shimniok 0:a6a169de725f 28
shimniok 0:a6a169de725f 29 void shell() {
shimniok 0:a6a169de725f 30 FILE *fp;
shimniok 0:a6a169de725f 31 char newpath[64], *arg, cmd[64], cmdline[64];
shimniok 0:a6a169de725f 32 bool done=false;
shimniok 0:a6a169de725f 33
shimniok 0:a6a169de725f 34 //Logger.SelectCRCMode(1);
shimniok 0:a6a169de725f 35
shimniok 0:a6a169de725f 36 //pc.printf("Formatting...\n");
shimniok 0:a6a169de725f 37 //int i = Logger.format(32);
shimniok 0:a6a169de725f 38 //pc.printf("format result: %d\n", i);
shimniok 0:a6a169de725f 39
shimniok 0:a6a169de725f 40 if ((fp = fopen("/log/message.txt", "w")) != NULL) {
shimniok 0:a6a169de725f 41 for (int i=0; i < 20; i++)
shimniok 0:a6a169de725f 42 fprintf(fp, "Hello, World!\n");
shimniok 0:a6a169de725f 43 fclose(fp);
shimniok 0:a6a169de725f 44 //pc.printf("created!\n");
shimniok 0:a6a169de725f 45 } else {
shimniok 0:a6a169de725f 46 pc.printf("Error creating file\n");
shimniok 0:a6a169de725f 47 }
shimniok 0:a6a169de725f 48 pc.printf("\n");
shimniok 0:a6a169de725f 49
shimniok 0:a6a169de725f 50 strcpy(cwd, "/log");
shimniok 0:a6a169de725f 51
shimniok 0:a6a169de725f 52 while (!done) {
shimniok 0:a6a169de725f 53 termInput(cmdline);
shimniok 0:a6a169de725f 54 arg = split(cmd, cmdline, 64, ' ');
shimniok 0:a6a169de725f 55 resolveDirectory(newpath, arg);
shimniok 0:a6a169de725f 56
shimniok 0:a6a169de725f 57 if (keypad.pressed) {
shimniok 0:a6a169de725f 58 keypad.pressed = false;
shimniok 0:a6a169de725f 59 break;
shimniok 0:a6a169de725f 60 }
shimniok 0:a6a169de725f 61
shimniok 0:a6a169de725f 62 if (debug) pc.printf("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", cmdline, cmd, arg, newpath);
shimniok 0:a6a169de725f 63
shimniok 0:a6a169de725f 64 if (!strcmp(cmd, "ls")) {
shimniok 0:a6a169de725f 65 ls(newpath);
shimniok 0:a6a169de725f 66 } else if (!strcmp(cmd, "cd")) {
shimniok 0:a6a169de725f 67 cd(newpath);
shimniok 0:a6a169de725f 68 } else if (!strcmp(cmd, "pwd")) {
shimniok 0:a6a169de725f 69 pwd();
shimniok 0:a6a169de725f 70 } else if (!strcmp(cmd, "head")) {
shimniok 0:a6a169de725f 71 head(newpath);
shimniok 0:a6a169de725f 72 } else if (!strcmp(cmd, "cat")) {
shimniok 0:a6a169de725f 73 cat(newpath);
shimniok 0:a6a169de725f 74 } else if (!strcmp(cmd, "send")) {
shimniok 0:a6a169de725f 75 send(newpath);
shimniok 0:a6a169de725f 76 } else if (!strcmp(cmd, "mkdir")) {
shimniok 0:a6a169de725f 77 mkdir(newpath, 1023);
shimniok 0:a6a169de725f 78 } else if (!strcmp(cmd, "debug")) {
shimniok 0:a6a169de725f 79 debug = !debug;
shimniok 0:a6a169de725f 80 } else if (!strcmp(cmd, "touch")) {
shimniok 0:a6a169de725f 81 touch(newpath);
shimniok 0:a6a169de725f 82 } else if (!strcmp(cmd, "rm")) {
shimniok 0:a6a169de725f 83 remove(newpath);
shimniok 0:a6a169de725f 84 } else if (!strcmp(cmd, "exit")) {
shimniok 0:a6a169de725f 85 done = true;
shimniok 0:a6a169de725f 86 } else if (cmd[0] == '\0') {
shimniok 0:a6a169de725f 87 // ignore
shimniok 0:a6a169de725f 88 } else {
shimniok 0:a6a169de725f 89 pc.printf("%s: command not found\n", cmd);
shimniok 0:a6a169de725f 90 }
shimniok 0:a6a169de725f 91 }
shimniok 0:a6a169de725f 92
shimniok 0:a6a169de725f 93 /*
shimniok 0:a6a169de725f 94 pc.printf("Printing splitName()\n");
shimniok 0:a6a169de725f 95 splitName("/SDCard/testdir", dirname, basename);
shimniok 0:a6a169de725f 96 pc.printf("%s %s\n", dirname, basename);
shimniok 0:a6a169de725f 97
shimniok 0:a6a169de725f 98 pc.printf("Printing resolveDirectory()\n");
shimniok 0:a6a169de725f 99 resolveDirectory(newpath, "test");
shimniok 0:a6a169de725f 100 pc.printf("%s\n", newpath);
shimniok 0:a6a169de725f 101 */
shimniok 0:a6a169de725f 102
shimniok 0:a6a169de725f 103 // remove("/SDCard/testdir/TEST.txt");
shimniok 0:a6a169de725f 104
shimniok 0:a6a169de725f 105 /*
shimniok 0:a6a169de725f 106 int test = rename("/SDCard/message.txt", "/SDCard/message2.txt");
shimniok 0:a6a169de725f 107 fp = fopen("/SDCard/message.txt", "a");
shimniok 0:a6a169de725f 108 fprintf(fp, " Result = %d", test);
shimniok 0:a6a169de725f 109 fclose(fp);
shimniok 0:a6a169de725f 110 */
shimniok 0:a6a169de725f 111
shimniok 0:a6a169de725f 112 pc.printf ("exiting shell\n");
shimniok 0:a6a169de725f 113
shimniok 0:a6a169de725f 114 return;
shimniok 0:a6a169de725f 115 }
shimniok 0:a6a169de725f 116
shimniok 0:a6a169de725f 117
shimniok 0:a6a169de725f 118 /** termInput
shimniok 0:a6a169de725f 119 *
shimniok 0:a6a169de725f 120 */
shimniok 0:a6a169de725f 121 void termInput(char *cmd) {
shimniok 0:a6a169de725f 122 int i=0;
shimniok 0:a6a169de725f 123 char c;
shimniok 0:a6a169de725f 124 bool done = false;
shimniok 0:a6a169de725f 125
shimniok 0:a6a169de725f 126 memset(cmd, 0, 64);
shimniok 0:a6a169de725f 127
shimniok 0:a6a169de725f 128 pc.printf("# ", cwd);
shimniok 0:a6a169de725f 129 do {
shimniok 0:a6a169de725f 130 cmd[i] = 0;
shimniok 0:a6a169de725f 131 c = pc.getc();
shimniok 0:a6a169de725f 132 if (c == '\r') { // if return is hit, we're done, don't add \r to cmd
shimniok 0:a6a169de725f 133 done = true;
shimniok 0:a6a169de725f 134 } else if (i < 64-1) {
shimniok 0:a6a169de725f 135 if (c == 0x7f || c == '\b') { // backspace or delete
shimniok 0:a6a169de725f 136 if (i > 0) { // if we're at the beginning, do nothing
shimniok 0:a6a169de725f 137 i--;
shimniok 0:a6a169de725f 138 pc.printf("\b \b");
shimniok 0:a6a169de725f 139 }
shimniok 0:a6a169de725f 140 } else {
shimniok 0:a6a169de725f 141 pc.printf("%c", c);
shimniok 0:a6a169de725f 142 cmd[i++] = c;
shimniok 0:a6a169de725f 143 }
shimniok 0:a6a169de725f 144 }
shimniok 0:a6a169de725f 145 } while (!done);
shimniok 0:a6a169de725f 146 pc.printf("\n");
shimniok 0:a6a169de725f 147 }
shimniok 0:a6a169de725f 148
shimniok 0:a6a169de725f 149 /** resolveDirectory
shimniok 0:a6a169de725f 150 * resolve the directory path provided, given the cwd
shimniok 0:a6a169de725f 151 */
shimniok 0:a6a169de725f 152 void resolveDirectory(char *newpath, char *path) {
shimniok 0:a6a169de725f 153 char dirname[32], basename[16];
shimniok 0:a6a169de725f 154
shimniok 0:a6a169de725f 155 /** absolute path */
shimniok 0:a6a169de725f 156 if (path[0] == '/') {
shimniok 0:a6a169de725f 157 strcpy(newpath, path);
shimniok 0:a6a169de725f 158 }
shimniok 0:a6a169de725f 159 /** relative path */
shimniok 0:a6a169de725f 160 else {
shimniok 0:a6a169de725f 161 strcpy(newpath, cwd);
shimniok 0:a6a169de725f 162 if (path[0] != 0) {
shimniok 0:a6a169de725f 163 if (newpath[strlen(newpath)-1] != '/')
shimniok 0:a6a169de725f 164 strcat(newpath, "/");
shimniok 0:a6a169de725f 165 strcat(newpath, path);
shimniok 0:a6a169de725f 166 }
shimniok 0:a6a169de725f 167 /** Resolve .. references */
shimniok 0:a6a169de725f 168 splitName(newpath, dirname, basename);
shimniok 0:a6a169de725f 169 if (!strcmp(basename, "..")) {
shimniok 0:a6a169de725f 170 splitName(dirname, newpath, basename);
shimniok 0:a6a169de725f 171 }
shimniok 0:a6a169de725f 172 }
shimniok 0:a6a169de725f 173 }
shimniok 0:a6a169de725f 174
shimniok 0:a6a169de725f 175 // copy t to s until space is reached
shimniok 0:a6a169de725f 176 // return location of delimiter+1 in t
shimniok 0:a6a169de725f 177 // if space not found, return t pointing to end of string
shimniok 0:a6a169de725f 178 // if s or t null, return null
shimniok 0:a6a169de725f 179 char *splitCmd(char *s, char *t, int max)
shimniok 0:a6a169de725f 180 {
shimniok 0:a6a169de725f 181 int i = 0;
shimniok 0:a6a169de725f 182
shimniok 0:a6a169de725f 183 if (s == 0 || t == 0)
shimniok 0:a6a169de725f 184 return 0;
shimniok 0:a6a169de725f 185
shimniok 0:a6a169de725f 186 while (*t != 0 && i < max) {
shimniok 0:a6a169de725f 187 *s++ = *t++;
shimniok 0:a6a169de725f 188 i++;
shimniok 0:a6a169de725f 189 if (*t == ' ') {
shimniok 0:a6a169de725f 190 t++;
shimniok 0:a6a169de725f 191 break;
shimniok 0:a6a169de725f 192 }
shimniok 0:a6a169de725f 193 }
shimniok 0:a6a169de725f 194 *s = 0;
shimniok 0:a6a169de725f 195
shimniok 0:a6a169de725f 196 return t;
shimniok 0:a6a169de725f 197 }
shimniok 0:a6a169de725f 198
shimniok 0:a6a169de725f 199 /** splitName
shimniok 0:a6a169de725f 200 * split the path into a dirname and a
shimniok 0:a6a169de725f 201 */
shimniok 0:a6a169de725f 202 void splitName(char *path, char *dirname, char *basename) {
shimniok 0:a6a169de725f 203 int sep;
shimniok 0:a6a169de725f 204
shimniok 0:a6a169de725f 205 sep = 0;
shimniok 0:a6a169de725f 206 if (debug) pc.printf("%d\n", strlen(path));
shimniok 0:a6a169de725f 207 for (int i=strlen(path)-1; i >= 0; i--) {
shimniok 0:a6a169de725f 208 if (debug) pc.printf("- %c\n", path[i]);
shimniok 0:a6a169de725f 209 sep = i;
shimniok 0:a6a169de725f 210 if (path[i] == '/') break;
shimniok 0:a6a169de725f 211 }
shimniok 0:a6a169de725f 212 for (int j=0; j < sep; j++) {
shimniok 0:a6a169de725f 213 if (debug) pc.printf("> %c\n", path[j]);
shimniok 0:a6a169de725f 214 dirname[j] = path[j];
shimniok 0:a6a169de725f 215 dirname[j+1] = 0;
shimniok 0:a6a169de725f 216 }
shimniok 0:a6a169de725f 217 for (int k=sep+1; k < strlen(path); k++) {
shimniok 0:a6a169de725f 218 if (debug) pc.printf("* %c\n", path[k]);
shimniok 0:a6a169de725f 219 basename[k-(sep+1)] = path[k];
shimniok 0:a6a169de725f 220 basename[k-sep] = 0;
shimniok 0:a6a169de725f 221 }
shimniok 0:a6a169de725f 222 if (debug) pc.printf("d:<%s> b:<%s>\n", dirname, basename);
shimniok 0:a6a169de725f 223 }
shimniok 0:a6a169de725f 224
shimniok 0:a6a169de725f 225 /** ls
shimniok 0:a6a169de725f 226 * lists files in the current working directory, 4 columns
shimniok 0:a6a169de725f 227 */
shimniok 0:a6a169de725f 228 void ls(char *path) {
shimniok 0:a6a169de725f 229 if (debug) pc.printf("%s\n", cwd);
shimniok 0:a6a169de725f 230 DIR *d;
shimniok 0:a6a169de725f 231 struct dirent *p;
shimniok 0:a6a169de725f 232
shimniok 0:a6a169de725f 233 int count=0;
shimniok 0:a6a169de725f 234 if ((d = opendir(path)) != NULL) {
shimniok 0:a6a169de725f 235 while ((p = readdir(d)) != NULL) {
shimniok 0:a6a169de725f 236 pc.printf("%12s", p->d_name);
shimniok 0:a6a169de725f 237 if (count++ >= 3) {
shimniok 0:a6a169de725f 238 count = 0;
shimniok 0:a6a169de725f 239 pc.printf("\n");
shimniok 0:a6a169de725f 240 }
shimniok 0:a6a169de725f 241 }
shimniok 0:a6a169de725f 242 pc.printf("\n");
shimniok 0:a6a169de725f 243 if (count < 3)
shimniok 0:a6a169de725f 244 pc.printf("\n");
shimniok 0:a6a169de725f 245 closedir(d);
shimniok 0:a6a169de725f 246 } else {
shimniok 0:a6a169de725f 247 pc.printf("%s: No such directory\n", path);
shimniok 0:a6a169de725f 248 }
shimniok 0:a6a169de725f 249 }
shimniok 0:a6a169de725f 250
shimniok 0:a6a169de725f 251 /** cd
shimniok 0:a6a169de725f 252 * changes current working directory
shimniok 0:a6a169de725f 253 */
shimniok 0:a6a169de725f 254 void cd(char *path) {
shimniok 0:a6a169de725f 255 strcpy(cwd, path);
shimniok 0:a6a169de725f 256 }
shimniok 0:a6a169de725f 257
shimniok 0:a6a169de725f 258 /** pwd
shimniok 0:a6a169de725f 259 * print current working directory
shimniok 0:a6a169de725f 260 */
shimniok 0:a6a169de725f 261 void pwd() {
shimniok 0:a6a169de725f 262 pc.printf("%s\n", cwd);
shimniok 0:a6a169de725f 263 }
shimniok 0:a6a169de725f 264
shimniok 0:a6a169de725f 265 /** touch
shimniok 0:a6a169de725f 266 * create an empty file
shimniok 0:a6a169de725f 267 */
shimniok 0:a6a169de725f 268 void touch(char *path) {
shimniok 0:a6a169de725f 269 FILE *fp;
shimniok 0:a6a169de725f 270 if ((fp = fopen(path, "w")) != NULL) {
shimniok 0:a6a169de725f 271 fclose(fp);
shimniok 0:a6a169de725f 272 } else {
shimniok 0:a6a169de725f 273 pc.printf("%s: No such file\n", path);
shimniok 0:a6a169de725f 274 }
shimniok 0:a6a169de725f 275 }
shimniok 0:a6a169de725f 276
shimniok 0:a6a169de725f 277 /** head
shimniok 0:a6a169de725f 278 * print the first 10 lines of a file
shimniok 0:a6a169de725f 279 */
shimniok 0:a6a169de725f 280 void head(char *path) {
shimniok 0:a6a169de725f 281 FILE *fp;
shimniok 0:a6a169de725f 282 char line = 0;
shimniok 0:a6a169de725f 283
shimniok 0:a6a169de725f 284 if ((fp = fopen(path, "r")) != NULL) {
shimniok 0:a6a169de725f 285 while (!feof(fp) && line++ < 10) {
shimniok 0:a6a169de725f 286 fgets(buf, 128, fp);
shimniok 0:a6a169de725f 287 pc.printf("%s", buf);
shimniok 0:a6a169de725f 288 }
shimniok 0:a6a169de725f 289 fclose(fp);
shimniok 0:a6a169de725f 290 } else {
shimniok 0:a6a169de725f 291 pc.printf("%s: No such file\n", path);
shimniok 0:a6a169de725f 292 }
shimniok 0:a6a169de725f 293 }
shimniok 0:a6a169de725f 294
shimniok 0:a6a169de725f 295 /** cat
shimniok 0:a6a169de725f 296 * display the content of a file
shimniok 0:a6a169de725f 297 */
shimniok 0:a6a169de725f 298 void cat(char *path) {
shimniok 0:a6a169de725f 299 FILE *fp;
shimniok 0:a6a169de725f 300
shimniok 0:a6a169de725f 301 if ((fp = fopen(path, "r")) != NULL) {
shimniok 0:a6a169de725f 302 while (!feof(fp)) {
shimniok 0:a6a169de725f 303 if (fgets(buf, 127, fp) != NULL)
shimniok 0:a6a169de725f 304 pc.printf("%s", buf);
shimniok 0:a6a169de725f 305 }
shimniok 0:a6a169de725f 306 fclose(fp);
shimniok 0:a6a169de725f 307 } else {
shimniok 0:a6a169de725f 308 pc.printf("%s: No such file\n", path);
shimniok 0:a6a169de725f 309 }
shimniok 0:a6a169de725f 310 }
shimniok 0:a6a169de725f 311
shimniok 0:a6a169de725f 312 /** send
shimniok 0:a6a169de725f 313 * Simple serial file transfer protocol
shimniok 0:a6a169de725f 314 * Initiates escape sequence: ^A^B, sends filename, ^C, and then file
shimniok 0:a6a169de725f 315 * contents followed by ^D
shimniok 0:a6a169de725f 316 */
shimniok 0:a6a169de725f 317 void send(char *path) {
shimniok 0:a6a169de725f 318 FILE *fp;
shimniok 0:a6a169de725f 319 char dirname[32], basename[16];
shimniok 0:a6a169de725f 320
shimniok 0:a6a169de725f 321 if ((fp = fopen(path, "r")) != NULL) {
shimniok 0:a6a169de725f 322 splitName(path, dirname, basename);
shimniok 0:a6a169de725f 323 pc.printf("%c%c%s%c", 1, 2, basename, 3);
shimniok 0:a6a169de725f 324 while (!feof(fp)) {
shimniok 0:a6a169de725f 325 if (fgets(buf, 127, fp) != NULL)
shimniok 0:a6a169de725f 326 pc.printf("%s", buf);
shimniok 0:a6a169de725f 327 }
shimniok 0:a6a169de725f 328 fclose(fp);
shimniok 0:a6a169de725f 329 pc.printf("%c", 4);
shimniok 0:a6a169de725f 330 } else {
shimniok 0:a6a169de725f 331 pc.printf("%s: No such file\n", path);
shimniok 0:a6a169de725f 332 }
shimniok 0:a6a169de725f 333 }