Skip to content

Commit

Permalink
Merge pull request #6 from nhjschulz/development
Browse files Browse the repository at this point in the history
V3.0 Arduino library support
  • Loading branch information
nhjschulz authored Oct 20, 2024
2 parents c008f61 + a042c2e commit f399b13
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 39 additions & 21 deletions examples/CfsmBlink/CfsmBlink.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
4 changes: 2 additions & 2 deletions library.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name=CFSM
version=0.2.2
version=0.3.0
author=Haju Schulz <[email protected]>
maintainer=Haju Schulz <[email protected]>
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
Expand Down
26 changes: 13 additions & 13 deletions src/c_fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -82,18 +82,18 @@ 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;

/** 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;

/******************************************************************************
Expand All @@ -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
Expand All @@ -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.
Expand Down

0 comments on commit f399b13

Please sign in to comment.