Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: FRDM_K64F_IOT lpc1768_blinky
Shell.cpp
00001 #include "mbed.h" 00002 #include "cmsis_os.h" 00003 00004 #include <stdlib.h> 00005 #include <string.h> 00006 #include <stdarg.h> 00007 // cpp headers 00008 #include <string> 00009 #include <cctype> 00010 00011 00012 00013 #include "Shell.h" 00014 00015 00016 static char *_strtok(char *str, const char *delim, char **saveptr) 00017 { 00018 char *token; 00019 if (str) 00020 *saveptr = str; 00021 token = *saveptr; 00022 00023 if (!token) 00024 return NULL; 00025 00026 token += strspn(token, delim); 00027 *saveptr = strpbrk(token, delim); 00028 if (*saveptr) 00029 *(*saveptr)++ = '\0'; 00030 00031 return *token ? token : NULL; 00032 } 00033 00034 00035 Shell::Shell(Stream * channel) 00036 :_chp(channel) 00037 { 00038 _commands.clear(); 00039 } 00040 00041 void Shell::addCommand(std::string name, shellcmd_t func) 00042 { 00043 _commands.insert(std::pair<std::string, shellcmd_t>(name, func)); 00044 } 00045 00046 void Shell::start(osPriority priority, 00047 int stackSize, 00048 unsigned char *stack_pointer) 00049 { 00050 _thread = new Thread(Shell::threadHelper, this, priority, stackSize, stack_pointer); 00051 } 00052 00053 void Shell::threadHelper(const void * arg) 00054 { 00055 Shell * pinstance = static_cast<Shell *>(const_cast<void *>(arg)); 00056 00057 pinstance->shellMain(); 00058 } 00059 00060 void Shell::shellUsage(const char *p) 00061 { 00062 _chp->printf("Usage: %s\r\n", p); 00063 } 00064 00065 void Shell::listCommands() 00066 { 00067 std::map<std::string, shellcmd_t>::iterator it; 00068 for (it = _commands.begin(); it != _commands.end(); it++) 00069 _chp->printf("%s ", (*it).first.c_str()); 00070 } 00071 00072 bool Shell::cmdExec(char * name, int argc, char *argv[]) 00073 { 00074 std::map<std::string, shellcmd_t>::iterator it; 00075 it = _commands.find(std::string(name)); 00076 if (it != _commands.end()) 00077 { 00078 it->second(_chp, argc, argv); 00079 return true; 00080 } 00081 00082 return false; 00083 } 00084 00085 00086 void Shell::shellMain() 00087 { 00088 int n; 00089 char *lp, *cmd, *tokp; 00090 00091 _chp->printf("\r\nEmbed/RX Shell\r\n"); 00092 while (true) { 00093 _chp->printf(">> "); 00094 if (shellGetLine(line, sizeof(line))) { 00095 _chp->printf("\r\nlogout"); 00096 break; 00097 } 00098 // Get the command 00099 lp = _strtok(line, " \t", &tokp); 00100 cmd = lp; 00101 00102 // Get the arguments 00103 n = 0; 00104 while ((lp = _strtok(NULL, " \t", &tokp)) != NULL) { 00105 if (n >= SHELL_MAX_ARGUMENTS) { 00106 _chp->printf("too many arguments\r\n"); 00107 cmd = NULL; 00108 break; 00109 } 00110 args[n++] = lp; 00111 } 00112 args[n] = NULL; 00113 00114 // Determine the command 00115 if (cmd != NULL) 00116 { 00117 if (strcasecmp(cmd, "exit") == 0) // If "exit" 00118 { 00119 if (n > 0) { 00120 shellUsage("exit"); 00121 continue; 00122 } 00123 // Break here breaks the outer loop 00124 // hence, we exit the shell. 00125 break; 00126 } 00127 else if (strcasecmp(cmd, "help") == 0) // If "help" 00128 { 00129 if (n > 0) { 00130 shellUsage("help"); 00131 continue; 00132 } 00133 _chp->printf("Commands: help exit "); 00134 listCommands(); 00135 _chp->printf("\r\n"); 00136 } 00137 else if (!cmdExec(cmd, n, args)) // Finally call exec on the command 00138 { 00139 // If the command is unknown 00140 _chp->printf("%s", cmd); 00141 _chp->printf(" ?\r\n"); 00142 } 00143 } // cmd != NULL 00144 } 00145 } 00146 00147 bool Shell::shellGetLine(char *line, unsigned size) 00148 { 00149 char *p = line; 00150 00151 while (true) { 00152 char c; 00153 00154 if ((c = _chp->getc()) == 0) 00155 return true; 00156 if (c == 4) { 00157 _chp->printf("^D"); 00158 return true; 00159 } 00160 if (c == 8) { 00161 if (p != line) { 00162 _chp->putc(c); 00163 _chp->putc(0x20); 00164 _chp->putc(c); 00165 p--; 00166 } 00167 continue; 00168 } 00169 if (c == '\r') { 00170 _chp->printf("\r\n"); 00171 *p = 0; 00172 return false; 00173 } 00174 if (c < 0x20) 00175 continue; 00176 if (p < line + size - 1) { 00177 _chp->putc(c); 00178 *p++ = (char)c; 00179 } 00180 } 00181 }
Generated on Tue Jul 12 2022 19:14:34 by
1.7.2