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.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VarStore.cpp Source File

VarStore.cpp

00001 
00002 #include <string.h>
00003 #include  <stdio.h>
00004 #include "mbed.h"
00005 #include "rtos.h"
00006 
00007 
00008 extern "C" void mbed_reset();
00009 
00010 #include "VarStore.h"
00011 
00012 #define CI_SZ 100
00013 
00014 /* Constructor
00015 */
00016 VarStore::VarStore(     RawSerial *ser, int sz)
00017 {
00018     VarCounter=0;
00019     this->pc=ser;
00020     this->sz=sz;
00021     //Store=(VarItem *) malloc( sizeof(VarItem)*sz); doesn't work
00022     Store=new VarItem[sz];
00023 }
00024 
00025 /* destructor
00026 */
00027 VarStore::~VarStore()
00028 {
00029     //dtor
00030 }
00031 
00032 /* destructor
00033 */
00034 char *VarStore::Set(char *Input)
00035 {
00036     VarItem *V;
00037     char *Name;
00038 
00039    // beaware of puts  pc->printf("VarStore Set %s\n",Input);
00040 
00041     if(Input [0] == 's') {
00042         strtok(Input,":");
00043         Name=strtok(NULL,":");
00044         if((V=GetVar(Name)) != NULL)
00045             return  V->SetVal(strtok(NULL,":"))!= ERR ? Input : NULL;
00046     }
00047     return NULL;
00048 }
00049 
00050 
00051 /*
00052 ************************
00053 */
00054 int VarStore::Load(char *Name, void *VarPtr,VarTypes VarType )
00055 {
00056     return Load(Name, VarPtr,VarType,0 );
00057 }
00058 
00059 /*
00060 ************************
00061 */
00062 int VarStore::Load(char *Name, void *VarPtr,VarTypes VarType, int Size )
00063 {
00064    
00065     if(GetVar(Name) ==NULL) {
00066         
00067         if(VarCounter < sz) {
00068            
00069             Store[VarCounter].SetVar(VarType,VarPtr);
00070             Store[VarCounter].SetVarName(Name);
00071             Store[VarCounter].SetVarArraySize(Size);
00072             VarCounter++;
00073           
00074             return NULL;
00075         }
00076     }
00077   
00078     return ERR;
00079 }
00080 
00081 /*
00082 ************************
00083 */
00084 VarItem *VarStore::GetVar(char *Name)
00085 {
00086     for (int i=0; i<sz; i++)
00087         if((strcmp(Name,Store[i].GetVarName()))==0)
00088             return &Store[i];
00089 
00090     return NULL;
00091 }
00092 
00093 /*
00094 ************************
00095 */
00096 char*  VarStore::Get(char *Name)
00097 {
00098     VarItem *V;
00099     V=GetVar(Name);
00100     if(V!=NULL)
00101      return V->Dump();
00102     else
00103         return NULL;
00104 }
00105 
00106 /*
00107 ************************
00108 */
00109 void VarStore::Worker2()
00110 {
00111 
00112     static char c, *ret=STR_OK;// not NULL to start in no error state
00113 
00114     static int ci_counter=0;
00115     static char Cs[CI_SZ];
00116     if(VarStore::MyThis->pc->readable()) {
00117         c=VarStore::MyThis->pc->getc();
00118 
00119         if(ci_counter >= CI_SZ-1) {   // RESET too much input
00120             ci_counter=0;
00121             Cs[0]='\0';
00122         } else {
00123             if(c=='\r') {             // got a command lets see whan can be done
00124                 Cs[ci_counter]='\0';
00125                 ret=VarStore::MyThis->Do(Cs);
00126                 ci_counter=0;
00127                 Cs[0]='\0';
00128             } else {                 // no command yet, let's keep recording.
00129                 Cs[ci_counter]=c;
00130                 ci_counter++;
00131             }
00132         }
00133     }
00134 
00135     if(ret==NULL) {  // ups.....
00136         VarStore::MyThis->pc->puts(" error setting/getting var \n");
00137         ret=STR_OK;
00138     }
00139 
00140 }
00141 
00142 /*
00143 ** nuisances for mixing threads/static members etc
00144 */
00145 VarStore *VarStore::MyThis=NULL;   // used by the worker reading the terminal. Need to be initilized this way to avoid
00146 // compiling errors
00147 
00148 /*
00149 ************************
00150 */
00151 void VarStore::Worker(void const *args)
00152 {
00153 
00154     VarStore::MyThis=(VarStore *)args;
00155     VarStore::MyThis->pc->attach(&VarStore::Worker2);
00156     while(1) {
00157         Thread::wait(1000); // nothing to do here besides firing worker2 when input ready
00158     }
00159 
00160 }
00161 /*
00162 ************************
00163 */
00164 char  *VarStore::Do(char *str)
00165 {
00166     char *ret;
00167     if(str != NULL) {
00168 
00169         switch(*str) {
00170             case 's':  /// command s  s:varname:value or s:arrayname:value1,value2,value3  assign values at runtime
00171                 return VarStore::MyThis->Set(str);
00172             case 'd':  /// command d  d:variablename dumps content of variable to screen/console.
00173 
00174                 VarStore::MyThis->pc->puts(str);
00175                 VarStore::MyThis->pc->putc('\n');
00176                 
00177                 ret=strtok(str,":");
00178                 ret=strtok(NULL,":");
00179                 
00180                 ret=VarStore::MyThis->Get(ret);
00181              
00182                 if(ret!=NULL) {
00183                   VarStore::MyThis->pc->puts(ret);
00184                   VarStore::MyThis->pc->putc('\n');
00185                     return ret;
00186                 } else
00187                     return NULL;
00188             case 'r':   /// command r resets the mbed. If you previously downloaded a new version fo code, it will run.
00189                 mbed_reset();
00190                 return NULL;
00191             case 'w':   ///  command w   waits a number of miliseconds releasing the input console to be used for other stuff temporarily
00192                 strtok(str,":");
00193                 Thread::wait(atoi(strtok(NULL,":")));
00194                 return STR_OK;
00195         };
00196     }
00197     return NULL;
00198 }
00199