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.
Fork of stateScript_v2 by
behave.h
00001 //#include "mbed.h" 00002 #include <stdint.h> 00003 #include <string.h> 00004 #include <string> 00005 #include <vector> 00006 #include <list> 00007 #include <deque> 00008 #include <queue> 00009 #include "hardwareInterface.h" 00010 00011 00012 #define MBEDHARDWARE //here is where we define which platform we are compiling for 00013 //#define FPGAHARDWARE 00014 00015 #define MAXVARNAMESIZE 30 //The maximum number of characters of a variable name 00016 00017 00018 00019 00020 00021 #ifdef MBEDHARDWARE 00022 #include "mbedInterface.h" 00023 #endif 00024 #ifdef FPGAHARDWARE 00025 #include "fpgaInterface.h" 00026 #endif 00027 00028 /* 00029 #define NUMEVENTS 50 00030 #define NUMCONDITIONS 150 00031 #define NUMINTCOMPARE 150 00032 #define NUMACTIONS 150 00033 #define NUMPORTMESSAGES 150 00034 #define NUMINTOPERATIONS 150 00035 #define NUMDISPLAYACTIONS 30 00036 #define NUMTRIGGERACTIONS 30 00037 #define NUMFUNCTIONS 50 00038 #define INPUTCHARBUFFERSIZE 3072 00039 */ 00040 00041 #define ARITHMATIC_CONDITION 0 00042 #define OR_CONDITION 1 00043 #define AND_CONDITION 2 00044 00045 extern "C" void mbed_reset();//reset mbed through software 00046 00047 00048 00049 using namespace std; 00050 00051 class event; //we foreward declare this because of class interdependencies 00052 00053 //used in the digital port class to organize digital change events 00054 /* 00055 struct changeEvent { 00056 uint32_t timeStamp; 00057 bool triggered; 00058 };*/ 00059 00060 00061 //The digitalPort object directly controls and keeps data about the port. Each port has 00062 //one digital out and one digital in. 00063 class digitalPort { 00064 public: 00065 digitalPort(); 00066 //digitalPort(sDigitalOut* DOP, sDigitalIn* DIP); 00067 void init(sDigitalOut* DOP, sDigitalIn* DIP); 00068 void setDigitalOut(int outVal); 00069 //int getDigitalOut(); 00070 int getDigitalIn(); 00071 int getLastChangeState(); 00072 uint32_t getTimeSinceLastChange(); 00073 uint32_t lastChangeTime; 00074 uint32_t lastOutChangeTime; 00075 00076 void setTriggerUpEvent(event* eventInput); //attahces a routine to an upward change 00077 void setTriggerDownEvent(event* eventInput); //attahces a routine to a downward change 00078 //void addStateChange(int newState, uint32_t timeStamp); 00079 00080 bool update(); //called from the main loop 00081 00082 int inState; 00083 int outState; 00084 00085 bool outStateChanged; 00086 00087 event* triggerUpEventPtr; 00088 event* triggerDownEventPtr; 00089 00090 private: 00091 00092 sDigitalOut* outPin; 00093 sDigitalIn* inPin; 00094 int lastInState; 00095 uint32_t lastChangeInterval; 00096 00097 //changeEvent lastUpEvent; 00098 //changeEvent lastDownEvent; 00099 }; 00100 00101 00102 //an intVariable contains an integer value and the name of that variable within the script 00103 class intVariable { 00104 00105 public: 00106 intVariable(); 00107 intVariable(std::string& tagInput, int initialValue); 00108 void set(std::string& tagInput, int initialValue); 00109 int value; 00110 //string tag; 00111 char tag[MAXVARNAMESIZE+1]; 00112 bool isUsed; 00113 00114 }; 00115 00116 00117 //ACTION SECTION-- an 'action' is a command in the script. It can be a single command, 00118 //or a block containing a set of actions 00119 //------------------------------------------------------------------------------------ 00120 00121 //display actions are used to output text messages via the serial port. The user can display 00122 //either a static text string or the value of a single variable. 00123 class displayAction { 00124 00125 public: 00126 displayAction(); 00127 void set(int* variable, string varNameInput); 00128 void set(string text); 00129 bool isUsed; 00130 void execute(); 00131 void release(); 00132 00133 private: 00134 int* dVariable; 00135 string dText; 00136 00137 }; 00138 00139 class triggerFunctionAction { 00140 00141 public: 00142 triggerFunctionAction(); 00143 triggerFunctionAction(int functionNum); 00144 void set(int functionNum); 00145 bool isUsed; 00146 void execute(); 00147 void release(); 00148 private: 00149 int functionNum; 00150 00151 00152 }; 00153 00154 //intOpertaion is an action that does addition or subtraction of integers and returns/stores the result 00155 //these operation are very limited so far (only + or - allowed, and only one operation per object, 00156 //for example a = b + b works but a = b + c + d does not. The output value can also be set to a random number. 00157 class intOperation { 00158 00159 public: 00160 intOperation(); 00161 00162 /* 00163 intOperation(int randParam, const char* cmpString, int cmpValInput); 00164 intOperation(int randParam, const char* cmpString, int* cmpIntVarInput); 00165 intOperation(int* intVarInput, const char* cmpString, int cmpValInput); 00166 intOperation(int* intVarInput, const char* cmpString, int* cmpIntVarInput); 00167 intOperation(int* intVarInput, intOperation* operationInput); 00168 */ 00169 00170 ~intOperation(); 00171 00172 //Supported operations with rand: 00173 //a = rand(x) 00174 //a = rand(x) + 3 00175 //a = rand(x) + b 00176 void setRandOp(int randParam, const char* cmpString, int cmpValInput, bool flipped); 00177 void setRandOp(int randParam, const char* cmpString, int* cmpIntVarInput, bool flipped); 00178 00179 //Supported regular operations 00180 //a = 5 00181 //a = b 00182 //a = b + 6 00183 //a = b + c 00184 void set(int* intVarInput, const char* cmpString, int cmpValInput); 00185 void set(int* intVarInput, const char* cmpString, int* cmpIntVarInput); 00186 void set(int* intVarInput, intOperation* operationInput); 00187 00188 00189 //Supported operations with clock() 00190 //a = clock() 00191 //a = clock() + 5 00192 //a = clock() + b 00193 void setClockOp(int* intVarInput); 00194 void setClockOp(const char* cmpString, int cmpValInput, bool flip); 00195 void setClockOp(const char* cmpString, int* cmpIntVarInput, bool flip); 00196 00197 void release(); 00198 bool isUsed; 00199 int execute(); 00200 00201 private: 00202 int randHigh; 00203 int* cmpVal; 00204 int* intVal; 00205 intOperation* opPtr; 00206 bool cmpValGlobal; 00207 bool isClockAssign; //if the current clock value is part of the operation 00208 bool inputsFlipped; 00209 int (intOperation::*executePtr)(); 00210 int addAndStore(); 00211 int subtractAndStore(); 00212 int add(); 00213 int subtract(); 00214 int equals(); 00215 00216 }; 00217 00218 //portMessage is an action to change a digital port. So far, You can only change the digital out (0 or 1) 00219 class portMessage { 00220 public: 00221 00222 portMessage(); 00223 //portMessage(digitalPort* portIn, int whichToSet, int value); //whichToSet: 1 DigitalOut; 2 State 00224 //void setMessage(digitalPort* portIn, int whichToSet, int value); //whichToSet: 1 DigitalOut; 2 State 00225 //portMessage(int* portIn, int whichToSet, int value); //whichToSet: 00226 void setMessage(int* portIn, int whichToSet, int value, digitalPort* portVector); //whichToSet: 00227 00228 void execute(); 00229 void release(); 00230 bool isUsed; 00231 00232 private: 00233 int whichToSet; //hard coded port number 00234 int* port; //alternative variable port number 00235 int value; 00236 00237 digitalPort* portVector; 00238 00239 }; 00240 00241 //holder class for all possible actions. This include general system commands. 00242 class action { 00243 public: 00244 00245 action(); 00246 ~action(); 00247 action(intOperation* opInput); 00248 action(portMessage* messageInput); 00249 action(event* eventInput); 00250 //action(event* eventInput, uint32_t delay); 00251 action(displayAction* displayInput); 00252 action(sSound* soundInput); 00253 action(triggerFunctionAction* triggerFuncInput); 00254 action(int8_t sysCommandInput); //for general system commands 00255 00256 void set(intOperation* opInput); 00257 void set(portMessage* messageInput); 00258 void set(event* eventInput); 00259 //void set(event* eventInput, uint32_t delay); 00260 00261 void set(displayAction* displayInput); 00262 void set(sSound* soundInput); 00263 void set(triggerFunctionAction* triggerFuncInput); 00264 void set(int8_t sysCommandInput); 00265 void execute(); 00266 void execute(uint32_t blockExecTime); 00267 void release(); 00268 bool isUsed; 00269 00270 private: 00271 intOperation* op; 00272 portMessage* message; 00273 event* eventToCreate; 00274 displayAction* displayActionPtr; 00275 sSound* sound; 00276 triggerFunctionAction* triggerFunc; 00277 //uint32_t eventDelay; 00278 int8_t sysCommand; 00279 char actionType; 00280 00281 }; 00282 //----------------------------------------------------- 00283 00284 //CONDITION SECTION-- a 'condition' is used in the beginning of a block (if-else blocks or while blocks) 00285 //If the condition is true, the block is exectuted during a callback 00286 //------------------------------------------------------------------------------------ 00287 00288 00289 //intCompare is a condition class that compares the state value of a port or 00290 //an integer variable to another integer variable or operation output 00291 class intCompare { 00292 00293 public: 00294 intCompare(); 00295 intCompare(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse); 00296 intCompare(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse); 00297 intCompare(int* intVarInput, const char* cmpString, int cmpValInput); 00298 intCompare(int* intVarInput, const char* cmpString, int* cmpIntVarInput); 00299 intCompare(int* intVarInput, const char* cmpString, intOperation* cmpIntOpInput); 00300 intCompare(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse); 00301 00302 void set(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse); 00303 void set(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse); 00304 void set(int* intVarInput, const char* cmpString, int cmpValInput); 00305 void set(int* intVarInput, const char* cmpString, int* cmpIntVarInput); 00306 void set(int* intVarInput, const char* cmpString, intOperation* cmpIntOpInput); 00307 void set(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse); 00308 00309 void release(); 00310 00311 ~intCompare(); 00312 bool isTrue(); 00313 bool isUsed; 00314 00315 private: 00316 digitalPort* port; 00317 int* portValPtr; 00318 int* cmpVal; 00319 int* intVal; 00320 intOperation* intOp; 00321 void setPointer(const char* cmpString); 00322 void setPointer_operation(const char* cmpString); 00323 bool (intCompare::*isTruePtr)(); 00324 bool cmpValGlobal; 00325 bool greaterThan(); 00326 bool greaterOrEqual(); 00327 bool lessThan(); 00328 bool lessOrEqual(); 00329 bool equal(); 00330 bool notEqual(); 00331 bool greaterThan_op(); 00332 bool greaterOrEqual_op(); 00333 bool lessThan_op(); 00334 bool lessOrEqual_op(); 00335 bool equal_op(); 00336 bool notEqual_op(); 00337 }; 00338 00339 00340 //holder class for all possible conditions (so far only intCompare) 00341 class condition { 00342 public: 00343 00344 condition(); 00345 condition(intCompare* compareInput); 00346 condition(condition* condition1, char condType, condition* condition2); 00347 ~condition(); 00348 void set(intCompare* compareInput); 00349 void set(condition* condition1, char condType, condition* condition2); 00350 bool isTrue(); 00351 bool isUsed; 00352 void release(); //called when the event is no longer being used; 00353 private: 00354 00355 //char conditionType; //1 for intCompare 00356 intCompare* intCmp; 00357 condition* conditionPtrs[2]; 00358 char conditionType; 00359 00360 00361 }; 00362 //-------------------------------------------- 00363 00364 00365 //queueItem connects a pre-defined event with an exectution time. 00366 //They are placed in the eventQueue 00367 struct queueItem { 00368 uint32_t timeToExecute; 00369 event* eventPtr; 00370 }; 00371 00372 00373 //Organizes events in a temporal queue. check() is called from the main loop. 00374 //If the execution time of the event has passed, then the event is exectuted. 00375 class eventQueue { 00376 public: 00377 eventQueue(); 00378 void addEventToQueue(event* eventInput, uint32_t delay); 00379 void eraseQueue(); //clear all future events 00380 void check(void); 00381 00382 private: 00383 std::vector<queueItem> events; 00384 int queueSize; 00385 00386 }; 00387 00388 //An 'event' is a block of 'actions' that can be gated with a boolean 'condition' set. All 00389 //conditions in the set must be true for the block of actions to be executed. Right now, 00390 //there is no OR logic (||), only AND (&&). 00391 //The entire event is placed on the event queue to be executed at a given delay. 00392 //At that future time, the condition is checked and if true, the block of actions 00393 //is exectuted. Note: an 'action' can be another event (or even the parent event), allowing 00394 //nested 'if' and 'while' statements. 00395 class event { 00396 public: 00397 00398 event(); 00399 event(eventQueue* queueInput); 00400 ~event(); 00401 void setTimeLag(uint32_t timeLagInput); //the event will be exectuted at this time from now 00402 void setTimeLag(int* timeLagInput); //the event will be exectuted at this time from now 00403 void setWhileLoopPeriod(uint32_t period); 00404 void setWhileLoopPeriod(int* period); 00405 void addCondition(condition* conditionInput); //contains a set of conditions to check and a truth table 00406 bool isConditionTrue(void); //checks if the condition is true 00407 void addAction(action* actionInput); //called during script parsing, when the block is being defined 00408 void addToQueue(void); //places the event on the event queue with default time lag. When the time 00409 //lag has expired, the the block is executed 00410 void addToQueue(uint32_t delay); 00411 void execute(void); //Execute without checking the condition. Called only from the event queue 00412 void setNextElseEvent(event* eventInput); //allows for else event block 00413 uint32_t timeLag; //default time from now when the event will be executed (this is ignored once placed in event queue) 00414 int* timeLagVar; //exectution time lab defined by a variable 00415 eventQueue* queuePtr; 00416 void release(); //called when the event is no longer being used; 00417 00418 char blockType; //0 callback 00419 //1 if ... do block (with conditions) 00420 //2 do block (no conditions) 00421 //3 else if ... do block 00422 //4 else do (no conditions) 00423 //5 while ... do every ... block 00424 //6 else while ... do every ... block 00425 //7 then if ... do block 00426 //8 then do (no conditions) 00427 00428 uint32_t whileLoopPeriod; //if non-zero, the block is a while loop (executed at regular intervals) 00429 int* whileLoopPeriodVar; 00430 event* nextElseEventPtr; 00431 bool isUsed; 00432 bool timeLagIsConstant; 00433 bool whileLoopPeriodIsConstant; 00434 bool hasWhileLoop; 00435 00436 private: 00437 int numConditions; 00438 int numActions; 00439 condition* conditionToCheck; 00440 action* actionArray[20]; 00441 00442 //if statement (can be left empty, which is interpreted as 'true') 00443 //std::vector<condition*> conditionArray; 00444 //std::deque<action*> actionArray; 00445 00446 }; 00447 00448 //each functionItem help a poiter to an action, and the name of the function. Not currently in use. 00449 class functionItem { 00450 public: 00451 functionItem(action* actionInput, string tagInput); 00452 ~functionItem(); 00453 string tag; 00454 action* actionPtr; 00455 }; 00456 00457 class blockBuffer { 00458 00459 public: 00460 blockBuffer(); 00461 bool addLine(char* input, int numChars); 00462 string getNextLine(); 00463 int16_t linesAvailable(); 00464 bool empty(); 00465 void resetBuffer(); 00466 00467 private: 00468 #ifdef MBEDHARDWARE 00469 //On the MBED, we need to put this on a different memory bank 00470 __attribute((section("AHBSRAM1"),aligned)) char charBuffer[INPUTCHARBUFFERSIZE]; 00471 #else 00472 char charBuffer[INPUTCHARBUFFERSIZE]; 00473 #endif 00474 int16_t bufferWritePos; 00475 int16_t bufferReadPos; 00476 int16_t _linesAvailable; 00477 00478 }; 00479 00480 //Parser for the incoming text. The parser is called when a line terminates with a semicolon (;). 00481 //Only the final line in a callback block should have a semicolon. 00482 class scriptStream { 00483 public: 00484 scriptStream(digitalPort* portVectorInput, int numPortsInput, eventQueue* queueInput, sSystem* system); 00485 void parseBlock(); 00486 void addLineToCurrentBlock(char* lineInput); // if the line did not end with a semicolon, add it to the current block 00487 int* findIntVariable(string nameInput); //used to retrieve the pointer to the designated variable if it exists 00488 int* findIntVariable(const char* nameInput); //used to retrieve the pointer to the designated variable if it exists 00489 int* findIntVariable(const char* nameInput, int start, int end); //used to retrieve the pointer to the designated variable if it exists 00490 00491 bool createIntVariable(string nameInput); // creates a new interger variable 00492 action* evaluateAssignmentForAction(string expression); //parses a numerical assignment or operation (a = b - c) 00493 action* evaluateAssignmentForAction(const char* expression); //parses a numerical assignment or operation (a = b - c) 00494 00495 bool evaluateConditions(string& expression, event* currentEvent); //parses a condition statement (a == b && c > d) 00496 //condition* parseConditions(string& expression); //parses a condition statement (a == b && c > d) 00497 //std::size_t findFirstOrOutsideParenth(string& expression); 00498 //std::size_t findFirstAndOutsideParenth(string& expression); 00499 //bool isOutsideParenth(string& expression,std::size_t foundItem); 00500 00501 condition* parseConditions(const char* expression,int start, int end); //parses a condition statement (a == b && c > d) 00502 int findFirstOrOutsideParenth(const char* expression, int start, int end); 00503 int findFirstAndOutsideParenth(const char* expression, int start, int end); 00504 bool isOutsideParenth(const char* expression,int foundItem, int start, int end); 00505 bool isNum(const char* expression, int start, int end); 00506 bool areStringsSame(const char* str1, const char* str2, int start, int end); 00507 00508 int getRandomParam(string expression); 00509 int getRandomParam(const char* expression,int start,int end); 00510 00511 00512 int findStringLoc(const char* refString,const char* findString,int start, int end); 00513 00514 00515 00516 private: 00517 00518 int currentTriggerPort; 00519 int currentTriggerDir; 00520 int currentPort; 00521 int currentFunction; 00522 00523 string tmpLine; 00524 vector<string> tokens; 00525 00526 bool lineError; 00527 int blockDepth; 00528 bool ifBlockInit; 00529 bool whileBlockInit; 00530 bool elseFlag; 00531 bool thenFlag; 00532 bool expectingDoStatement; 00533 int currentDelay; 00534 event* tmpEvent; 00535 string tmpString; 00536 00537 vector<intVariable*> globalVariables; 00538 vector<event*> tmpEventPtrArray; 00539 //event* functionEventArray[NUMFUNCTIONS]; 00540 //bool functionSpotTaken[NUMFUNCTIONS]; 00541 00542 //vector<functionItem*> functionArray; //any blocks declared outsite callback blocks are stored here 00543 //list<string> currentBlock; 00544 blockBuffer currentBlock; 00545 digitalPort* portVector; 00546 sSystem* system; 00547 00548 00549 00550 int numPorts; 00551 eventQueue* queuePtr; 00552 00553 }; 00554 00555 00556 class mainLoop 00557 00558 { 00559 public: 00560 mainLoop(); 00561 void init(); 00562 void exec(); 00563 private: 00564 void eraseBuffer(); 00565 uint32_t currentDIOstate[2]; 00566 bool digitalInChanged; 00567 bool digitalOutChanged; 00568 scriptStream *parser; 00569 sSystem *hardware; //hardware interface 00570 sSerialPort *pc; //communication to computer 00571 char buffer[256]; 00572 digitalPort ports[NUMPORTS]; 00573 00574 00575 00576 };
Generated on Tue Jul 12 2022 17:07:31 by
1.7.2
