When debugging code it can be handy to examine/alter variables and to check the state of input lines. So your main program can run and you have access to alter variables and run functions from a terminal. In this sample the main program is just a loop that flashes an LED. In that loop a periodic call is made to ShellTC which handles any commands from the serial terminal. The code is a bit quirky(it was originally written for a very resource limited device) but it works well enough to be useful, hence its published. More details in the main.cpp
.
shell.cpp@0:87e65dabdb95, 2012-10-25 (annotated)
- Committer:
- jont
- Date:
- Thu Oct 25 21:57:40 2012 +0000
- Revision:
- 0:87e65dabdb95
First release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jont | 0:87e65dabdb95 | 1 | /* Copyright (c) <year> <copyright holders>, MIT License |
jont | 0:87e65dabdb95 | 2 | * |
jont | 0:87e65dabdb95 | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
jont | 0:87e65dabdb95 | 4 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
jont | 0:87e65dabdb95 | 5 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
jont | 0:87e65dabdb95 | 6 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
jont | 0:87e65dabdb95 | 7 | * furnished to do so, subject to the following conditions: |
jont | 0:87e65dabdb95 | 8 | * |
jont | 0:87e65dabdb95 | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
jont | 0:87e65dabdb95 | 10 | * substantial portions of the Software. |
jont | 0:87e65dabdb95 | 11 | * |
jont | 0:87e65dabdb95 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
jont | 0:87e65dabdb95 | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
jont | 0:87e65dabdb95 | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
jont | 0:87e65dabdb95 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
jont | 0:87e65dabdb95 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
jont | 0:87e65dabdb95 | 17 | */ |
jont | 0:87e65dabdb95 | 18 | /*++++++ SHELL.C +++++++*/ |
jont | 0:87e65dabdb95 | 19 | //jont@ninelocks.com |
jont | 0:87e65dabdb95 | 20 | //(c)jont@ninelocks.com 1992-2012 |
jont | 0:87e65dabdb95 | 21 | //Nasty nasty code intedned to help debug other bits of the project |
jont | 0:87e65dabdb95 | 22 | //If you dont like the code, fix it :-) |
jont | 0:87e65dabdb95 | 23 | |
jont | 0:87e65dabdb95 | 24 | #include "string.h" |
jont | 0:87e65dabdb95 | 25 | #include "sio.h" |
jont | 0:87e65dabdb95 | 26 | #include "shell.h" |
jont | 0:87e65dabdb95 | 27 | #include "mbed.h" |
jont | 0:87e65dabdb95 | 28 | #include "mon.h" |
jont | 0:87e65dabdb95 | 29 | |
jont | 0:87e65dabdb95 | 30 | |
jont | 0:87e65dabdb95 | 31 | char current_level; /* current mode */ |
jont | 0:87e65dabdb95 | 32 | |
jont | 0:87e65dabdb95 | 33 | void ShellCommand(void); /* decides if command */ |
jont | 0:87e65dabdb95 | 34 | void nu_command(void); /* finds commmand */ |
jont | 0:87e65dabdb95 | 35 | int SplitCommand(void); /* split up the command line */ |
jont | 0:87e65dabdb95 | 36 | void ShellTC(void); /* called by timed irq */ |
jont | 0:87e65dabdb95 | 37 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 38 | // Init the flags etc |
jont | 0:87e65dabdb95 | 39 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 40 | void ShellInit() { |
jont | 0:87e65dabdb95 | 41 | current_level = '%'; /* the prompt symbol*/ |
jont | 0:87e65dabdb95 | 42 | commandWaiting = false; |
jont | 0:87e65dabdb95 | 43 | |
jont | 0:87e65dabdb95 | 44 | } |
jont | 0:87e65dabdb95 | 45 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 46 | /* first stop is command */ |
jont | 0:87e65dabdb95 | 47 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 48 | |
jont | 0:87e65dabdb95 | 49 | void ShellCommand(void) { |
jont | 0:87e65dabdb95 | 50 | /* for limited damage could strip results codes here |
jont | 0:87e65dabdb95 | 51 | * so we dont need to check level for each alterable varaiable |
jont | 0:87e65dabdb95 | 52 | */ |
jont | 0:87e65dabdb95 | 53 | |
jont | 0:87e65dabdb95 | 54 | valueChange = SplitCommand(); /* split up the command line */ |
jont | 0:87e65dabdb95 | 55 | //show how command line was broken up to help debug your commands |
jont | 0:87e65dabdb95 | 56 | if (valueChange != 0) { |
jont | 0:87e65dabdb95 | 57 | printf("\n\rCOMMAND %s", comBuff); |
jont | 0:87e65dabdb95 | 58 | printf("\n\rVALUE %s", comBuff+valueChange); |
jont | 0:87e65dabdb95 | 59 | } |
jont | 0:87e65dabdb95 | 60 | |
jont | 0:87e65dabdb95 | 61 | nu_command(); /* call command router */ |
jont | 0:87e65dabdb95 | 62 | printf("\n\r%c", current_level); |
jont | 0:87e65dabdb95 | 63 | |
jont | 0:87e65dabdb95 | 64 | } |
jont | 0:87e65dabdb95 | 65 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 66 | /* SplitCommand separates arg and value */ |
jont | 0:87e65dabdb95 | 67 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 68 | /* |
jont | 0:87e65dabdb95 | 69 | * cuts command line in to command |
jont | 0:87e65dabdb95 | 70 | * and an value argument for those which can be set |
jont | 0:87e65dabdb95 | 71 | */ |
jont | 0:87e65dabdb95 | 72 | |
jont | 0:87e65dabdb95 | 73 | int SplitCommand(void) { |
jont | 0:87e65dabdb95 | 74 | int index; |
jont | 0:87e65dabdb95 | 75 | int valueIndex; |
jont | 0:87e65dabdb95 | 76 | int length; |
jont | 0:87e65dabdb95 | 77 | length = strlen(comBuff); |
jont | 0:87e65dabdb95 | 78 | // printf("\n\rLength %d", length); |
jont | 0:87e65dabdb95 | 79 | for (index= 0; index <= length; index++) { |
jont | 0:87e65dabdb95 | 80 | if ( (comBuff[index] == 0x20 ) && (index != length - 1)) { |
jont | 0:87e65dabdb95 | 81 | comBuff[index]='\0'; /* terminate string */ |
jont | 0:87e65dabdb95 | 82 | valueIndex = index+1; |
jont | 0:87e65dabdb95 | 83 | printf("\n\rVindex %d", valueIndex); |
jont | 0:87e65dabdb95 | 84 | return(valueIndex); |
jont | 0:87e65dabdb95 | 85 | } |
jont | 0:87e65dabdb95 | 86 | } |
jont | 0:87e65dabdb95 | 87 | return(0); |
jont | 0:87e65dabdb95 | 88 | } |
jont | 0:87e65dabdb95 | 89 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 90 | /* nu_command finds and initiates command */ |
jont | 0:87e65dabdb95 | 91 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 92 | /* |
jont | 0:87e65dabdb95 | 93 | * this looks up a command and despatches to its handler |
jont | 0:87e65dabdb95 | 94 | * new functions only need to be added to the array command_table |
jont | 0:87e65dabdb95 | 95 | * and of course be declared before the table |
jont | 0:87e65dabdb95 | 96 | */ |
jont | 0:87e65dabdb95 | 97 | void nu_command(void) { |
jont | 0:87e65dabdb95 | 98 | int i = 0; |
jont | 0:87e65dabdb95 | 99 | // printf("\n\rNC Says %s\n\r",comBuff); |
jont | 0:87e65dabdb95 | 100 | do { |
jont | 0:87e65dabdb95 | 101 | |
jont | 0:87e65dabdb95 | 102 | // printf("\n\rNC2 Says %s",command_table[i].commandp); |
jont | 0:87e65dabdb95 | 103 | if (strcmp(comBuff, command_table[i].commandp) == 0) { |
jont | 0:87e65dabdb95 | 104 | command_table[i].func_p(); |
jont | 0:87e65dabdb95 | 105 | |
jont | 0:87e65dabdb95 | 106 | } |
jont | 0:87e65dabdb95 | 107 | i++; |
jont | 0:87e65dabdb95 | 108 | } while (strcmp ( command_table[i].commandp, "") != 0); |
jont | 0:87e65dabdb95 | 109 | |
jont | 0:87e65dabdb95 | 110 | } |
jont | 0:87e65dabdb95 | 111 | |
jont | 0:87e65dabdb95 | 112 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 113 | /* the handler that does the actual command */ |
jont | 0:87e65dabdb95 | 114 | /*======================================================================*/ |
jont | 0:87e65dabdb95 | 115 | |
jont | 0:87e65dabdb95 | 116 | void ShellTC() { |
jont | 0:87e65dabdb95 | 117 | |
jont | 0:87e65dabdb95 | 118 | if ( commandWaiting == true ) { |
jont | 0:87e65dabdb95 | 119 | ShellCommand(); |
jont | 0:87e65dabdb95 | 120 | commandWaiting = false; |
jont | 0:87e65dabdb95 | 121 | } |
jont | 0:87e65dabdb95 | 122 | |
jont | 0:87e65dabdb95 | 123 | } |