Table driven Finite State Machine library based on the Harel state machine, supporting actions on transitions, state entry and state exit. Comes with example illustrating use with interrupts and timers. 03/01/2010 - fixed potential memory leak in DebugTrace.
Revision 0:918566a376fb, committed 2010-01-03
- Comitter:
- snatch59
- Date:
- Sun Jan 03 11:56:03 2010 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 918566a376fb DebugTrace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DebugTrace.cpp Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,143 @@ +/* +* DebugTrace. Allows dumping debug messages/values to serial or +* to file. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of DebugTrace. +* +* DebugTrace is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DebugTrace is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "DebugTrace.h" +#include <mbed.h> +#include <stdarg.h> +#include <string.h> + +Serial logSerial(USBTX, USBRX); +LocalFileSystem local("local"); + +const char* FILE_PATH = "/local/"; +const char* EXTN = ".bak"; + +DebugTrace::DebugTrace(eLog on, eLogTarget mode, const char* fileName, int maxSize) : + enabled(on), logMode(mode), maxFileSize(maxSize), currentFileSize(0), + logFileStatus(0) +{ + // allocate memory for file name strings + int str_size = (strlen(fileName) + strlen(FILE_PATH) + strlen(EXTN) + 1) * sizeof(char); + logFile = (char*)malloc(str_size); + logFileBackup = (char*)malloc(str_size); + + // add path to log file name + strcpy(logFile, FILE_PATH); + strcat(logFile, fileName); + + // create backup file name + strcpy(logFileBackup, logFile); + strcpy(logFileBackup, strtok(logFileBackup, ".")); + strcat(logFileBackup, EXTN); +} + +DebugTrace::~DebugTrace() +{ + // dust to dust, ashes to ashes + if (logFile != NULL) free(logFile); + if (logFileBackup != NULL) free(logFileBackup); +} + +void DebugTrace::clear() +{ + // don't care about whether these fail + remove(logFile); + remove(logFileBackup); +} + +void DebugTrace::backupLog() +{ + // delete previous backup file + if (remove(logFileBackup)) + { + // standard copy stuff + char ch; + FILE* to = fopen(logFileBackup, "wb"); + if (NULL != to) + { + FILE* from = fopen(logFile, "rb"); + if (NULL != from) + { + while(!feof(from)) + { + ch = fgetc(from); + if (ferror(from)) break; + + if(!feof(from)) fputc(ch, to); + if (ferror(to)) break; + } + } + + if (NULL != from) fclose(from); + if (NULL != to) fclose(to); + } + } + + // now delete the log file, so we are ready to start again + // even if backup creation failed - the show must go on! + logFileStatus = remove(logFile); +} + +void DebugTrace::traceOut(const char* fmt, ...) +{ + if (enabled) + { + va_list ap; // argument list pointer + va_start(ap, fmt); + + if (TO_SERIAL == logMode) + { + vfprintf(logSerial, fmt, ap); + } + else // TO_FILE + { + if (0 == logFileStatus) // otherwise we failed to remove a full log file + { + // Write data to file. Note the file size may go over limit + // as we check total size afterwards, using the size written to file. + // This is not a big issue, as this mechanism is only here + // to stop the file growing unchecked. Just remember log file sizes may + // be some what over (as apposed to some what under), so don't push it + // with the max file size. + FILE* fp = fopen(logFile, "a"); + if (NULL == fp) + { + va_end(ap); + return; + } + int size_written = vfprintf(fp, fmt, ap); + fclose(fp); + + // check if we are over the max file size + // if so backup file and start again + currentFileSize += size_written; + if (currentFileSize >= maxFileSize) + { + backupLog(); + currentFileSize = 0; + } + } + } + + va_end(ap); + } +}
diff -r 000000000000 -r 918566a376fb DebugTrace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DebugTrace.h Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,50 @@ +/* +* DebugTrace. Allows dumping debug messages/values to serial or +* to file. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of DebugTrace. +* +* DebugTrace is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DebugTrace is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef SNATCH59_DEBUGTRACE_H +#define SNATCH59_DEBUGTRACE_H + +enum eLog {OFF, ON}; +enum eLogTarget {TO_SERIAL, TO_FILE}; + +class DebugTrace +{ +public: + DebugTrace(eLog on, eLogTarget mode, const char* fileName = "log.txt", const int maxSize = 1024); + ~DebugTrace(); + + void clear(); + void traceOut(const char* fmt, ...); + +private: + eLog enabled; + eLogTarget logMode; + int maxFileSize; + int currentFileSize; + char* logFile; + char* logFileBackup; + int logFileStatus; // if things go wrong, don't write any more data to file + + void backupLog(); +}; + +#endif
diff -r 000000000000 -r 918566a376fb FSM.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FSM.h Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,192 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef SNATCH59_FSM_H +#define SNATCH59_FSM_H + +#include <mbed.h> +#include "FSMDefs.h" + +STATE_TEMPLATE_ class State; + +TRANS_DEF_TEMPLATE_ +struct TransitionDefinition +{ + const char* ownerState; + int eventId; + StateBehaviour mode; + ActionPtrType action; + const char* newState; +}; + +TRANS_DEF_TEMPLATE_ +class StateDefinition +{ +public: + const char* stateName; + ActionPtrType stateEntryAction; + ActionPtrType stateExitAction; +}; + +#include "State.h" + +FSM_TEMPLATE_ +class FiniteStateMachine +{ +public: + FiniteStateMachine(); + ~FiniteStateMachine(); + + void initialize(StateObjectType* owner, + const STATE_DEFINITION_* states, const int total_states, + const TRANSITION_DEFINITION_* transitions, const int total_transitions, + const char* this_state); + void traverse(const int new_event); + void forceToState(const char* stat_name); + bool isState(const char* this_state) const; + const char* getCurrentStateName() const; + +private: + void addStates(const STATE_DEFINITION_* states, const int total_states, + const TRANSITION_DEFINITION_* &transitions, const int total_transitions); + void executeTraversal(const int event); + + // Data Members + STATE_* currentState; + int totalStates; + StateObjectType* itsStateObject; + STATE_* itsStates[maxStates]; +}; + +FSM_TEMPLATE_ +inline const char* FINITE_STATE_MACHINE_::getCurrentStateName() const +{ + return (currentState->getName()); +} + +FSM_TEMPLATE_ +inline bool FINITE_STATE_MACHINE_::isState(const char* this_state) const +{ + if (0 == strcmp(currentState->getName(), this_state)) return true; + + return false; +} + +FSM_TEMPLATE_ +FINITE_STATE_MACHINE_::FiniteStateMachine() : totalStates(0), currentState(NULL) +{ +} + +FSM_TEMPLATE_ +FINITE_STATE_MACHINE_::~FiniteStateMachine() +{ + if (itsStates != NULL) + { + // delete all its States + for (int i = 0; i < totalStates; i++) + { + delete itsStates[i]; + } + } +} + +FSM_TEMPLATE_ +void FINITE_STATE_MACHINE_::initialize(StateObjectType* owner, + const STATE_DEFINITION_* states, const int total_states, + const TRANSITION_DEFINITION_* transitions, const int total_transitions, + const char* this_state) +{ + itsStateObject = owner; + + for (int k = 0; k < total_states; k++) + { + addStates(states, total_states, transitions, total_transitions); + } + + forceToState(this_state); +} + +FSM_TEMPLATE_ +void FINITE_STATE_MACHINE_::traverse(const int new_event) +{ + if (0 == totalStates) + { + return; + } + + STATE_TRANSITION_* associated_transition = NULL; + STATE_* new_state = currentState->match(new_event, associated_transition); + + if (new_state != NULL && associated_transition != NULL) + { + StateBehaviour behaviour = associated_transition->getStateBehaviour(); + + if (actions == behaviour) + { + currentState->doExitAction(itsStateObject); + } + + currentState = new_state; + + associated_transition->doAction(itsStateObject); + + if (actions == behaviour) + { + new_state->doEntryAction(itsStateObject); + } + } +} + +FSM_TEMPLATE_ +void FINITE_STATE_MACHINE_::forceToState(const char* state_name) +{ + for (int i = 0; i < totalStates; i++) + { + if (0 == strcmp(itsStates[i]->getName(), state_name)) + { + currentState = itsStates[i]; + break; + } + } +} + +FSM_TEMPLATE_ +void FINITE_STATE_MACHINE_::addStates(const STATE_DEFINITION_* states, const int total_states, + const TRANSITION_DEFINITION_* &transitions, const int total_transitions) +{ + for (int i = 0; i < total_states; i++) + { + + itsStates[i] = new STATE_(states[i].stateName, + states[i].stateEntryAction, + states[i].stateExitAction); + } + totalStates = total_states; + + for (int i = 0; i < total_states; i++) + { + itsStates[i]->addTransitions(transitions, total_transitions, itsStates, total_states); + } +} + +#endif
diff -r 000000000000 -r 918566a376fb FSMDefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FSMDefs.h Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,39 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef SNATCH59_FSMDEFS_H +#define SNATCH59_FSMDEFS_H + +#define FSM_TEMPLATE_ template<class StateObjectType, class ActionPtrType, int maxStates> +#define STATE_TEMPLATE_ template<class StateObjectType, class ActionPtrType> +#define TRANS_DEF_TEMPLATE_ template<class ActionPtrType> + +#define FINITE_STATE_MACHINE_ FiniteStateMachine<StateObjectType, ActionPtrType, maxStates> +#define STATE_ State<StateObjectType, ActionPtrType> +#define STATE_TRANSITION_ StateTransition<StateObjectType, ActionPtrType> +#define TRANSITION_DEFINITION_ TransitionDefinition<ActionPtrType> +#define STATE_DEFINITION_ StateDefinition<ActionPtrType> + +enum StateBehaviour {actions, noactions}; + +#endif
diff -r 000000000000 -r 918566a376fb MyInterruptHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyInterruptHandler.cpp Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,106 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <mbed.h> +#include "MyInterruptHandler.h" +#include "FSMDefs.h" +#include "FSM.h" +#include "DebugTrace.h" + +DebugTrace pc(ON, TO_SERIAL); + +typedef void (MyInterruptHandler::* clientActionPtr)( ); + +// states +const char* S_START = "Start"; +const char* S_LED_SEQ1 = "LedSeq1"; +const char* S_LED_SEQ2 = "LedSeq2"; + +const StateDefinition<clientActionPtr> states[] = + {// state, entry action, exit action + S_START, NULL, NULL, + S_LED_SEQ1, &MyInterruptHandler::ledSequence1, NULL, + S_LED_SEQ2, &MyInterruptHandler::ledSequence2, NULL + }; +const int total_states = sizeof(states)/sizeof(StateDefinition<clientActionPtr>); + +// transitions +const TransitionDefinition<clientActionPtr> transitions[] = + {// start state, event, type transition action, end state + S_START, (int)intr1, actions, NULL, S_LED_SEQ1, + S_LED_SEQ1, (int)intr2, actions, NULL, S_LED_SEQ2, + S_LED_SEQ2, (int)intr1, actions, NULL, S_LED_SEQ1, + S_LED_SEQ1, (int)tickr1, actions, NULL, S_LED_SEQ1, + S_LED_SEQ2, (int)tickr1, actions, NULL, S_LED_SEQ2, + }; +const int total_transitions = sizeof(transitions)/sizeof(TransitionDefinition<clientActionPtr>); + +// declare a state machine +static FiniteStateMachine<MyInterruptHandler, clientActionPtr, total_states> itsStateMachine; + +// put LEDs on a bus for convenience +BusOut leds(LED1, LED2, LED3, LED4); + + +MyInterruptHandler::MyInterruptHandler() : interrupt1(p5), interrupt2(p6) +{ + // init state machine + itsStateMachine.initialize(this, states, total_states, transitions, total_transitions, S_START); + + // attach callbacks for interrupts and timer + interrupt1.rise(this, &MyInterruptHandler::intrhandler1); + interrupt2.rise(this, &MyInterruptHandler::intrhandler2); + ticker1.attach(this, &MyInterruptHandler::tickerhandler1, 0.5); +} + +void MyInterruptHandler::processEvent(clientEvent event_id) +{ + itsStateMachine.traverse((int)event_id); +} + +void MyInterruptHandler::intrhandler1() +{ + processEvent(intr1); +} + +void MyInterruptHandler::intrhandler2() +{ + processEvent(intr2); +} + +void MyInterruptHandler::tickerhandler1() +{ + processEvent(tickr1); +} + +void MyInterruptHandler::ledSequence1() +{ + pc.traceOut("ledSequence1\r\n"); + (0x00 == leds || 0x08 == leds) ? leds = 1 : leds = leds << 1; +} + +void MyInterruptHandler::ledSequence2() +{ + pc.traceOut("ledSequence2\r\n"); + (0x00 == leds || 0x01 == leds) ? leds = 8 : leds = leds >> 1; +}
diff -r 000000000000 -r 918566a376fb MyInterruptHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyInterruptHandler.h Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,52 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef SNATCH59_MYINTERRUPTHANDLER_H +#define SNATCH59_MYINTERRUPTHANDLER_H + +// event names +enum clientEvent {intr1, intr2, tickr1}; + +class MyInterruptHandler +{ +public: + MyInterruptHandler(); + + void processEvent(clientEvent eventId); + + // interrupt & timer handlers + void intrhandler1(); + void intrhandler2(); + void tickerhandler1(); + + // state or transition actions + void ledSequence1(); + void ledSequence2(); + +private: + InterruptIn interrupt1; + InterruptIn interrupt2; + Ticker ticker1; +}; + +#endif
diff -r 000000000000 -r 918566a376fb State.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/State.h Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,162 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef SNATCH59_STATE_H +#define SNATCH59_STATE_H + +#include <mbed.h> +#include "FSMDefs.h" +#include "FSM.h" + +STATE_TEMPLATE_ class StateTransition; + +#include "StateTransition.h" + +STATE_TEMPLATE_ +class State +{ + +public: + State(const char* state_name, ActionPtrType entry_action_ptr, ActionPtrType exit_action_ptr); + ~State( ); + + STATE_* match(const int event_id, STATE_TRANSITION_* &transition) const; + void addTransitions(const TRANSITION_DEFINITION_* &transitions, const int total_transitions, + STATE_** states, const int total_states); + void doEntryAction(StateObjectType* &its_state_object); + void doExitAction(StateObjectType* &its_state_object); + const char* getName( ) const; + +private: + const char* name; + int totalTransitions; + ActionPtrType entryAction; + ActionPtrType exitAction; + STATE_TRANSITION_** itsTransitions; +}; + +STATE_TEMPLATE_ +inline const char* STATE_::getName() const +{ + return name; +} + +STATE_TEMPLATE_ +STATE_::State(const char* state_name, ActionPtrType entry_action_ptr, ActionPtrType exit_action_ptr) : + name(state_name), entryAction(entry_action_ptr), + exitAction(exit_action_ptr), totalTransitions(0) +{ +} + +STATE_TEMPLATE_ +STATE_::~State( ) +{ + if (itsTransitions != NULL) + { + for (int i = 0; i < totalTransitions; i++) + { + delete itsTransitions[i]; + } + + // dust to dust, ashes to ashes + free(itsTransitions); + } +} + +STATE_TEMPLATE_ +void STATE_::addTransitions(const TRANSITION_DEFINITION_* &transitions, const int total_transitions, + STATE_** states, const int total_states) +{ + int tcount = 0; + for (int i = 0; i < total_transitions; i++) + { + TRANSITION_DEFINITION_ tdef = transitions[i]; + if (0 == strcmp(name, tdef.ownerState)) + { + tcount++; + } + } + + itsTransitions = (STATE_TRANSITION_**)malloc(sizeof(STATE_TRANSITION_*)*tcount); + + for (int i = 0; i < total_transitions; i++) + { + TRANSITION_DEFINITION_ tdef = transitions[i]; + if (0 == strcmp(name, tdef.ownerState)) + { + STATE_* new_state_ptr = NULL; + for (int k = 0; k < total_states; k++) + { + if (0 == strcmp(states[k]->getName(), tdef.newState)) + { + new_state_ptr = states[k]; + break; + } + } + + itsTransitions[totalTransitions++] = + new STATE_TRANSITION_(tdef.eventId, tdef.action, new_state_ptr, tdef.mode); + } + } +} + +STATE_TEMPLATE_ +STATE_* STATE_::match(const int event_id, STATE_TRANSITION_* &transition) const +{ + if (0 == totalTransitions) + { + return NULL; + } + + STATE_* new_state = NULL; + + int i = 0; + do + { + new_state = itsTransitions[i]->match(event_id); + transition = itsTransitions[i++]; + } + while (NULL == new_state && i < totalTransitions); + + return new_state; +} + +STATE_TEMPLATE_ +void STATE_::doEntryAction(StateObjectType* &its_state_object) +{ + if (entryAction != NULL) + { + (its_state_object->*entryAction)( ); + } +} + +STATE_TEMPLATE_ +void STATE_::doExitAction(StateObjectType* &its_state_object) +{ + if (exitAction != NULL) + { + (its_state_object->*exitAction)( ); + } +} + +#endif
diff -r 000000000000 -r 918566a376fb StateTransition.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/StateTransition.h Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,81 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef SNATCH59_STATETRANSITION_H +#define SNATCH59_STATETRANSITION_H + +#include <mbed.h> +#include "FSMDefs.h" + +STATE_TEMPLATE_ class State; + +#include "State.h" + +STATE_TEMPLATE_ +class StateTransition +{ + +public: + StateTransition(int event_id, ActionPtrType action, STATE_* state_ptr, StateBehaviour behaviour); + + STATE_* match(const int event_id) const; + void doAction(StateObjectType* &its_state_object) const; + StateBehaviour getStateBehaviour() const; + +private: + int eventId; + ActionPtrType action; + STATE_* newState; + StateBehaviour mode; +}; + +STATE_TEMPLATE_ +inline STATE_* STATE_TRANSITION_::match(const int event_id) const +{ + if (eventId == event_id) return newState; + + return NULL; +} + +STATE_TEMPLATE_ +inline StateBehaviour STATE_TRANSITION_::getStateBehaviour() const +{ + return mode; +} + +STATE_TEMPLATE_ +STATE_TRANSITION_::StateTransition(int event_id, ActionPtrType action_ptr, STATE_* state_ptr, StateBehaviour behaviour) : + eventId(event_id), action(action_ptr), newState(state_ptr), mode(behaviour) +{ +} + +STATE_TEMPLATE_ +void STATE_TRANSITION_::doAction(StateObjectType* &its_state_object) const +{ + if (action != NULL) + { + (its_state_object->*action)( ); + } +} + +#endif
diff -r 000000000000 -r 918566a376fb main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,36 @@ +/* +* FiniteStateMachine. Table driven Finite State Machine library +* based on theHarel state machine, supporting actions on transitions, state +* entry and state exit. +* +* Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> +* +* This file is part of FiniteStateMachine. +* +* FiniteStateMachine is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* FiniteStateMachine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <mbed.h> +#include "MyInterruptHandler.h" + +int main() +{ + MyInterruptHandler client; + + while (true) + { + wait(5); + } + +}
diff -r 000000000000 -r 918566a376fb mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Jan 03 11:56:03 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0