library to modify and read program variable in runtime from a serial console. You can reset as well the mbed from the console without pushing buttons. Handy for debugging from the online compiler as you can change the behavior of the program without need to recompile each time.
VarStore.cpp@17:8c20a558d34f, 2014-08-26 (annotated)
- Committer:
- julmbed
- Date:
- Tue Aug 26 09:39:40 2014 +0000
- Revision:
- 17:8c20a558d34f
- Parent:
- 13:e1ba5bf9e51f
fixed doc typos
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
julmbed | 0:85afbf3c9fad | 1 | |
julmbed | 0:85afbf3c9fad | 2 | #include <string.h> |
julmbed | 0:85afbf3c9fad | 3 | #include <stdio.h> |
julmbed | 0:85afbf3c9fad | 4 | #include "mbed.h" |
julmbed | 0:85afbf3c9fad | 5 | #include "rtos.h" |
julmbed | 8:934ec53fe2c0 | 6 | |
julmbed | 0:85afbf3c9fad | 7 | |
julmbed | 2:a59207652720 | 8 | extern "C" void mbed_reset(); |
julmbed | 2:a59207652720 | 9 | |
julmbed | 0:85afbf3c9fad | 10 | #include "VarStore.h" |
julmbed | 0:85afbf3c9fad | 11 | |
julmbed | 0:85afbf3c9fad | 12 | #define CI_SZ 100 |
julmbed | 0:85afbf3c9fad | 13 | |
julmbed | 13:e1ba5bf9e51f | 14 | /* Constructor |
julmbed | 13:e1ba5bf9e51f | 15 | */ |
julmbed | 12:e9c8d2d9ac71 | 16 | VarStore::VarStore( RawSerial *ser, int sz) |
julmbed | 0:85afbf3c9fad | 17 | { |
julmbed | 0:85afbf3c9fad | 18 | VarCounter=0; |
julmbed | 8:934ec53fe2c0 | 19 | this->pc=ser; |
julmbed | 12:e9c8d2d9ac71 | 20 | this->sz=sz; |
julmbed | 13:e1ba5bf9e51f | 21 | //Store=(VarItem *) malloc( sizeof(VarItem)*sz); doesn't work |
julmbed | 12:e9c8d2d9ac71 | 22 | Store=new VarItem[sz]; |
julmbed | 0:85afbf3c9fad | 23 | } |
julmbed | 0:85afbf3c9fad | 24 | |
julmbed | 13:e1ba5bf9e51f | 25 | /* destructor |
julmbed | 13:e1ba5bf9e51f | 26 | */ |
julmbed | 0:85afbf3c9fad | 27 | VarStore::~VarStore() |
julmbed | 0:85afbf3c9fad | 28 | { |
julmbed | 0:85afbf3c9fad | 29 | //dtor |
julmbed | 0:85afbf3c9fad | 30 | } |
julmbed | 0:85afbf3c9fad | 31 | |
julmbed | 13:e1ba5bf9e51f | 32 | /* destructor |
julmbed | 13:e1ba5bf9e51f | 33 | */ |
julmbed | 2:a59207652720 | 34 | char *VarStore::Set(char *Input) |
julmbed | 0:85afbf3c9fad | 35 | { |
julmbed | 0:85afbf3c9fad | 36 | VarItem *V; |
julmbed | 0:85afbf3c9fad | 37 | char *Name; |
julmbed | 0:85afbf3c9fad | 38 | |
julmbed | 8:934ec53fe2c0 | 39 | // beaware of puts pc->printf("VarStore Set %s\n",Input); |
julmbed | 8:934ec53fe2c0 | 40 | |
julmbed | 0:85afbf3c9fad | 41 | if(Input [0] == 's') { |
julmbed | 0:85afbf3c9fad | 42 | strtok(Input,":"); |
julmbed | 0:85afbf3c9fad | 43 | Name=strtok(NULL,":"); |
julmbed | 0:85afbf3c9fad | 44 | if((V=GetVar(Name)) != NULL) |
julmbed | 2:a59207652720 | 45 | return V->SetVal(strtok(NULL,":"))!= ERR ? Input : NULL; |
julmbed | 0:85afbf3c9fad | 46 | } |
julmbed | 2:a59207652720 | 47 | return NULL; |
julmbed | 0:85afbf3c9fad | 48 | } |
julmbed | 0:85afbf3c9fad | 49 | |
julmbed | 0:85afbf3c9fad | 50 | |
julmbed | 13:e1ba5bf9e51f | 51 | /* |
julmbed | 13:e1ba5bf9e51f | 52 | ************************ |
julmbed | 13:e1ba5bf9e51f | 53 | */ |
julmbed | 0:85afbf3c9fad | 54 | int VarStore::Load(char *Name, void *VarPtr,VarTypes VarType ) |
julmbed | 0:85afbf3c9fad | 55 | { |
julmbed | 0:85afbf3c9fad | 56 | return Load(Name, VarPtr,VarType,0 ); |
julmbed | 0:85afbf3c9fad | 57 | } |
julmbed | 0:85afbf3c9fad | 58 | |
julmbed | 13:e1ba5bf9e51f | 59 | /* |
julmbed | 13:e1ba5bf9e51f | 60 | ************************ |
julmbed | 13:e1ba5bf9e51f | 61 | */ |
julmbed | 0:85afbf3c9fad | 62 | int VarStore::Load(char *Name, void *VarPtr,VarTypes VarType, int Size ) |
julmbed | 0:85afbf3c9fad | 63 | { |
julmbed | 13:e1ba5bf9e51f | 64 | |
julmbed | 0:85afbf3c9fad | 65 | if(GetVar(Name) ==NULL) { |
julmbed | 13:e1ba5bf9e51f | 66 | |
julmbed | 12:e9c8d2d9ac71 | 67 | if(VarCounter < sz) { |
julmbed | 13:e1ba5bf9e51f | 68 | |
julmbed | 0:85afbf3c9fad | 69 | Store[VarCounter].SetVar(VarType,VarPtr); |
julmbed | 0:85afbf3c9fad | 70 | Store[VarCounter].SetVarName(Name); |
julmbed | 0:85afbf3c9fad | 71 | Store[VarCounter].SetVarArraySize(Size); |
julmbed | 0:85afbf3c9fad | 72 | VarCounter++; |
julmbed | 13:e1ba5bf9e51f | 73 | |
julmbed | 12:e9c8d2d9ac71 | 74 | return NULL; |
julmbed | 0:85afbf3c9fad | 75 | } |
julmbed | 0:85afbf3c9fad | 76 | } |
julmbed | 13:e1ba5bf9e51f | 77 | |
julmbed | 0:85afbf3c9fad | 78 | return ERR; |
julmbed | 0:85afbf3c9fad | 79 | } |
julmbed | 0:85afbf3c9fad | 80 | |
julmbed | 13:e1ba5bf9e51f | 81 | /* |
julmbed | 13:e1ba5bf9e51f | 82 | ************************ |
julmbed | 13:e1ba5bf9e51f | 83 | */ |
julmbed | 0:85afbf3c9fad | 84 | VarItem *VarStore::GetVar(char *Name) |
julmbed | 0:85afbf3c9fad | 85 | { |
julmbed | 12:e9c8d2d9ac71 | 86 | for (int i=0; i<sz; i++) |
julmbed | 0:85afbf3c9fad | 87 | if((strcmp(Name,Store[i].GetVarName()))==0) |
julmbed | 0:85afbf3c9fad | 88 | return &Store[i]; |
julmbed | 0:85afbf3c9fad | 89 | |
julmbed | 0:85afbf3c9fad | 90 | return NULL; |
julmbed | 0:85afbf3c9fad | 91 | } |
julmbed | 0:85afbf3c9fad | 92 | |
julmbed | 13:e1ba5bf9e51f | 93 | /* |
julmbed | 13:e1ba5bf9e51f | 94 | ************************ |
julmbed | 13:e1ba5bf9e51f | 95 | */ |
julmbed | 0:85afbf3c9fad | 96 | char* VarStore::Get(char *Name) |
julmbed | 0:85afbf3c9fad | 97 | { |
julmbed | 0:85afbf3c9fad | 98 | VarItem *V; |
julmbed | 8:934ec53fe2c0 | 99 | V=GetVar(Name); |
julmbed | 9:d081aa4e4418 | 100 | if(V!=NULL) |
julmbed | 9:d081aa4e4418 | 101 | return V->Dump(); |
julmbed | 9:d081aa4e4418 | 102 | else |
julmbed | 0:85afbf3c9fad | 103 | return NULL; |
julmbed | 0:85afbf3c9fad | 104 | } |
julmbed | 0:85afbf3c9fad | 105 | |
julmbed | 13:e1ba5bf9e51f | 106 | /* |
julmbed | 13:e1ba5bf9e51f | 107 | ************************ |
julmbed | 13:e1ba5bf9e51f | 108 | */ |
julmbed | 10:34d368966675 | 109 | void VarStore::Worker2() |
julmbed | 0:85afbf3c9fad | 110 | { |
julmbed | 8:934ec53fe2c0 | 111 | |
julmbed | 6:9848fdaf2ad9 | 112 | static char c, *ret=STR_OK;// not NULL to start in no error state |
julmbed | 8:934ec53fe2c0 | 113 | |
julmbed | 6:9848fdaf2ad9 | 114 | static int ci_counter=0; |
julmbed | 6:9848fdaf2ad9 | 115 | static char Cs[CI_SZ]; |
julmbed | 8:934ec53fe2c0 | 116 | if(VarStore::MyThis->pc->readable()) { |
julmbed | 8:934ec53fe2c0 | 117 | c=VarStore::MyThis->pc->getc(); |
julmbed | 2:a59207652720 | 118 | |
julmbed | 13:e1ba5bf9e51f | 119 | if(ci_counter >= CI_SZ-1) { // RESET too much input |
julmbed | 8:934ec53fe2c0 | 120 | ci_counter=0; |
julmbed | 8:934ec53fe2c0 | 121 | Cs[0]='\0'; |
julmbed | 8:934ec53fe2c0 | 122 | } else { |
julmbed | 13:e1ba5bf9e51f | 123 | if(c=='\r') { // got a command lets see whan can be done |
julmbed | 8:934ec53fe2c0 | 124 | Cs[ci_counter]='\0'; |
julmbed | 8:934ec53fe2c0 | 125 | ret=VarStore::MyThis->Do(Cs); |
julmbed | 0:85afbf3c9fad | 126 | ci_counter=0; |
julmbed | 0:85afbf3c9fad | 127 | Cs[0]='\0'; |
julmbed | 13:e1ba5bf9e51f | 128 | } else { // no command yet, let's keep recording. |
julmbed | 8:934ec53fe2c0 | 129 | Cs[ci_counter]=c; |
julmbed | 8:934ec53fe2c0 | 130 | ci_counter++; |
julmbed | 0:85afbf3c9fad | 131 | } |
julmbed | 0:85afbf3c9fad | 132 | } |
julmbed | 8:934ec53fe2c0 | 133 | } |
julmbed | 0:85afbf3c9fad | 134 | |
julmbed | 13:e1ba5bf9e51f | 135 | if(ret==NULL) { // ups..... |
julmbed | 8:934ec53fe2c0 | 136 | VarStore::MyThis->pc->puts(" error setting/getting var \n"); |
julmbed | 8:934ec53fe2c0 | 137 | ret=STR_OK; |
julmbed | 8:934ec53fe2c0 | 138 | } |
julmbed | 8:934ec53fe2c0 | 139 | |
julmbed | 0:85afbf3c9fad | 140 | } |
julmbed | 0:85afbf3c9fad | 141 | |
julmbed | 13:e1ba5bf9e51f | 142 | /* |
julmbed | 13:e1ba5bf9e51f | 143 | ** nuisances for mixing threads/static members etc |
julmbed | 13:e1ba5bf9e51f | 144 | */ |
julmbed | 8:934ec53fe2c0 | 145 | VarStore *VarStore::MyThis=NULL; // used by the worker reading the terminal. Need to be initilized this way to avoid |
julmbed | 8:934ec53fe2c0 | 146 | // compiling errors |
julmbed | 13:e1ba5bf9e51f | 147 | |
julmbed | 13:e1ba5bf9e51f | 148 | /* |
julmbed | 13:e1ba5bf9e51f | 149 | ************************ |
julmbed | 13:e1ba5bf9e51f | 150 | */ |
julmbed | 5:47b67a7c0bb7 | 151 | void VarStore::Worker(void const *args) |
julmbed | 5:47b67a7c0bb7 | 152 | { |
julmbed | 5:47b67a7c0bb7 | 153 | |
julmbed | 5:47b67a7c0bb7 | 154 | VarStore::MyThis=(VarStore *)args; |
julmbed | 10:34d368966675 | 155 | VarStore::MyThis->pc->attach(&VarStore::Worker2); |
julmbed | 5:47b67a7c0bb7 | 156 | while(1) { |
julmbed | 13:e1ba5bf9e51f | 157 | Thread::wait(1000); // nothing to do here besides firing worker2 when input ready |
julmbed | 5:47b67a7c0bb7 | 158 | } |
julmbed | 5:47b67a7c0bb7 | 159 | |
julmbed | 5:47b67a7c0bb7 | 160 | } |
julmbed | 13:e1ba5bf9e51f | 161 | /* |
julmbed | 13:e1ba5bf9e51f | 162 | ************************ |
julmbed | 13:e1ba5bf9e51f | 163 | */ |
julmbed | 7:fafe81a95c08 | 164 | char *VarStore::Do(char *str) |
julmbed | 2:a59207652720 | 165 | { |
julmbed | 2:a59207652720 | 166 | char *ret; |
julmbed | 2:a59207652720 | 167 | if(str != NULL) { |
julmbed | 2:a59207652720 | 168 | |
julmbed | 2:a59207652720 | 169 | switch(*str) { |
julmbed | 13:e1ba5bf9e51f | 170 | case 's': /// command s s:varname:value or s:arrayname:value1,value2,value3 assign values at runtime |
julmbed | 6:9848fdaf2ad9 | 171 | return VarStore::MyThis->Set(str); |
julmbed | 13:e1ba5bf9e51f | 172 | case 'd': /// command d d:variablename dumps content of variable to screen/console. |
julmbed | 8:934ec53fe2c0 | 173 | |
julmbed | 9:d081aa4e4418 | 174 | VarStore::MyThis->pc->puts(str); |
julmbed | 9:d081aa4e4418 | 175 | VarStore::MyThis->pc->putc('\n'); |
julmbed | 9:d081aa4e4418 | 176 | |
julmbed | 8:934ec53fe2c0 | 177 | ret=strtok(str,":"); |
julmbed | 8:934ec53fe2c0 | 178 | ret=strtok(NULL,":"); |
julmbed | 8:934ec53fe2c0 | 179 | |
julmbed | 8:934ec53fe2c0 | 180 | ret=VarStore::MyThis->Get(ret); |
julmbed | 8:934ec53fe2c0 | 181 | |
julmbed | 2:a59207652720 | 182 | if(ret!=NULL) { |
julmbed | 9:d081aa4e4418 | 183 | VarStore::MyThis->pc->puts(ret); |
julmbed | 9:d081aa4e4418 | 184 | VarStore::MyThis->pc->putc('\n'); |
julmbed | 2:a59207652720 | 185 | return ret; |
julmbed | 2:a59207652720 | 186 | } else |
julmbed | 2:a59207652720 | 187 | return NULL; |
julmbed | 13:e1ba5bf9e51f | 188 | case 'r': /// command r resets the mbed. If you previously downloaded a new version fo code, it will run. |
julmbed | 2:a59207652720 | 189 | mbed_reset(); |
julmbed | 2:a59207652720 | 190 | return NULL; |
julmbed | 13:e1ba5bf9e51f | 191 | case 'w': /// command w waits a number of miliseconds releasing the input console to be used for other stuff temporarily |
julmbed | 3:cf43e6de918e | 192 | strtok(str,":"); |
julmbed | 3:cf43e6de918e | 193 | Thread::wait(atoi(strtok(NULL,":"))); |
julmbed | 3:cf43e6de918e | 194 | return STR_OK; |
julmbed | 2:a59207652720 | 195 | }; |
julmbed | 2:a59207652720 | 196 | } |
julmbed | 2:a59207652720 | 197 | return NULL; |
julmbed | 2:a59207652720 | 198 | } |
julmbed | 2:a59207652720 | 199 |