diff --git a/README.md b/README.md index 1c143c2..99684d6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![PlatformIO Registry](https://badges.registry.platformio.org/packages/nhjschulz/library/CFSM.svg)](https://registry.platformio.org/libraries/nhjschulz/CFSM) [![arduino-library-badge](https://www.ardu-badge.com/badge/CFSM.svg?)](https://www.ardu-badge.com/CFSM) -# CFSM - A State Pattern Approach for C-Programs +# CFSM - A State Design Pattern for State Machines in C-Language. Finite state machines (FSM) are present in almost every non trivial program. Guides on how to implement them are part of many programming diff --git a/examples/CfsmBlink/CfsmBlink.ino b/examples/CfsmBlink/CfsmBlink.ino index bfae6c3..0c93cbf 100644 --- a/examples/CfsmBlink/CfsmBlink.ino +++ b/examples/CfsmBlink/CfsmBlink.ino @@ -24,59 +24,77 @@ void LedOnState_enter(cfsm_Ctx * fsm); // Forward declaration for entering LED Off state void LedOffState_enter(cfsm_Ctx * fsm); -cfsm_Ctx blinkFsm; // CFSM state machine date +cfsm_Ctx blinkFsm; // A CFSM state machine. -uint64_t ledUpdateTime = 0; // Hold time of last LED update. -int LED_PIN = LED_BUILTIN; // Used LED Pin +uint64_t ledUpdateTime = 0; // Time of last LED update. + +const int LED_PIN = LED_BUILTIN; // Used LED Pin +const int LED_TOGGLE_EVENT = 1; // Signal LED toggle to FSM. void setup() { pinMode(LED_PIN, OUTPUT); + ledUpdateTime = millis(); - // setup FSM and enter LED ON state + // Setup FSM and enter LED ON state. cfsm_init(&blinkFsm, NULL); cfsm_transition(&blinkFsm, LedOnState_enter); } void loop() { - cfsm_process(&blinkFsm); // Do work in current CFSM state + cfsm_process(&blinkFsm); // Do work in current state. + + if ((millis() - ledUpdateTime) >= 1000) { + ledUpdateTime = millis(); + + // Another second has passed, toggle LED on or off. + cfsm_event(&blinkFsm, LED_TOGGLE_EVENT); + } } -// CFSM On state handler functions +// CFSM On state handler functions: -void LedOnState_process(cfsm_Ctx * fsm) +void LedOnState_event(cfsm_Ctx * fsm, int eventId) { - if ((millis() - ledUpdateTime) >= 1000ull) - { - // LED On time has expired, switch to off state + if (eventId == LED_TOGGLE_EVENT) { + // LED On time has expired, switch to OFF state. cfsm_transition(fsm, LedOffState_enter); } } +void LedOnState_process(cfsm_Ctx * fsm) +{ + // Add cyclic executed work for this state here. +} + void LedOnState_enter(cfsm_Ctx * fsm) { - fsm->onProcess = LedOnState_process; // register state process handler + fsm->onEvent = LedOnState_event; // Register state event handler. + fsm->onProcess = LedOnState_process; // Register handler for processing. - digitalWrite(LED_PIN, HIGH); // turn the LED on - ledUpdateTime = millis(); // store update time + digitalWrite(LED_PIN, HIGH); // Turn the LED on. } -// CFSM Off state handler functions +// CFSM Off state handler functions: -void LedOffState_process(cfsm_Ctx * fsm) +void LedOffState_event(cfsm_Ctx * fsm, int eventId) { - if ((millis() - ledUpdateTime) >= 1000ull) - { - // LED Off time has expired, switch to on state + if (eventId == LED_TOGGLE_EVENT) { + // LED Off time has expired, switch to ON state. cfsm_transition(fsm, LedOnState_enter); } } +void LedOffState_process(cfsm_Ctx * fsm) +{ + // Add cyclic executed work for this state here. +} + void LedOffState_enter(cfsm_Ctx * fsm) { - fsm->onProcess = LedOffState_process; // register state process handler + fsm->onEvent = LedOffState_event; // Register state event handler. + fsm->onProcess = LedOffState_process; // Register handler for processing. - digitalWrite(LED_PIN, LOW); // turn the LED off - ledUpdateTime = millis(); // store update time + digitalWrite(LED_PIN, LOW); // Turn the LED off. } diff --git a/library.json b/library.json index e5de7a1..ff9bdd2 100644 --- a/library.json +++ b/library.json @@ -1,8 +1,8 @@ { "$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json", "name": "CFSM", - "version": "0.2.2", - "description": "A State Design Pattern Approach for C-Programs", + "version": "0.3.0", + "description": "A State Design Pattern for State Machines in C-Language", "keywords": "state design pattern, FSM, C-Language", "repository": { "type": "git", diff --git a/library.properties b/library.properties index 61b0760..786f76a 100644 --- a/library.properties +++ b/library.properties @@ -1,8 +1,8 @@ name=CFSM -version=0.2.2 +version=0.3.0 author=Haju Schulz maintainer=Haju Schulz -sentence=A State Design Pattern Approach for C-Programs. +sentence=A State Design Pattern for State Machines in C-Language. paragraph=CFSM follows a simplistic approach for the C-Language to implement maintainable state machines according to the STATE design pattern. This differentiates it from other solutions that often rely on complex macros to construct state handlers. category=Other url=https://github.com/nhjschulz/cfsm diff --git a/src/c_fsm.h b/src/c_fsm.h index 0364784..1705216 100644 --- a/src/c_fsm.h +++ b/src/c_fsm.h @@ -53,8 +53,8 @@ extern "C" { *****************************************************************************/ #define CFSM_VER_MAJOR 0 /**< semantic versioning major X.x.x */ -#define CFSM_VER_MINOR 2 /**< semantic versioning minor x.X.x */ -#define CFSM_VER_PATCH 2 /**< semantic versioning patch x.x.X */ +#define CFSM_VER_MINOR 3 /**< semantic versioning minor x.X.x */ +#define CFSM_VER_PATCH 0 /**< semantic versioning patch x.x.X */ /****************************************************************************** * Types and Classes @@ -82,7 +82,7 @@ typedef void (*cfsm_EventFunction)(struct cfsm_Ctx * fsm, int eventId); typedef void (*cfsm_ProcessFunction)(struct cfsm_Ctx * fsm); /** - * @brief Instance data pointer as void * to accept any pointer typ. + * @brief Instance data pointer as void * to accept any pointer type. * */ typedef void *cfsm_InstanceDataPtr; @@ -90,10 +90,10 @@ typedef void *cfsm_InstanceDataPtr; /** The CFSM context data structure */ typedef struct cfsm_Ctx { - cfsm_InstanceDataPtr ctxPtr; /**< context instance data */ - cfsm_TransitionFunction onLeave; /**< operation run on leave */ - cfsm_ProcessFunction onProcess; /**< cyclic operations */ - cfsm_EventFunction onEvent; /**< report event to the state */ + cfsm_InstanceDataPtr ctxPtr; /**< Context instance data */ + cfsm_TransitionFunction onLeave; /**< Operation to run on leave */ + cfsm_ProcessFunction onProcess; /**< Cyclic processoperation */ + cfsm_EventFunction onEvent; /**< Report event to active state */ } cfsm_Ctx; /****************************************************************************** @@ -116,22 +116,22 @@ typedef struct cfsm_Ctx { void cfsm_init(cfsm_Ctx * fsm, cfsm_InstanceDataPtr instanceData); /** - * @brief Transition given fsm to a new state + * @brief Transition given fsm to a new state. * - * Perform a state transition be calling the function given by enterFunc. + * Perform a state transition by calling the function given by enterFunc. * The called function is expected to update the state handlers in * the state structure. Unused handlers needs not to be set. * Passing NULL as enterfunc triggers the leave handler for the current * state and clears all handler which stops the FSM from doing anything. * * @param fsm The fsm data structure - * @param enterFunc The enter function for the new fsm state (may be NULL) + * @param enterFunc The enter operation for the new fsm state (may be NULL) * @since 0.1.0 */ void cfsm_transition(struct cfsm_Ctx * fsm, cfsm_TransitionFunction enterFunc); /** - * @brief Execute a process cycle to the current fsm state + * @brief Execute a process cycle to the current fsm state. * * Call the process handler of the current fsm state. This * function is expected to be called cyclicly. The function @@ -151,8 +151,8 @@ void cfsm_process(struct cfsm_Ctx * fsm); * signaled to the current state. An event is just an * application defined integer id. It has no meaning to * the FSM itself. Events provide a method to react to - * application events when they occure, instead of polling - * for them during process cycles. + * application events instead of polling them during + * process cycles. * * An example for an event id could be a UI button press * to trigger a state dependend reaction.