Skip to content

Commit

Permalink
Add (Doxygen) comments
Browse files Browse the repository at this point in the history
  • Loading branch information
6arms1leg committed Apr 18, 2022
1 parent dc8e8cf commit b67677b
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 28 deletions.
12 changes: 7 additions & 5 deletions src/SMfsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ void SMfsm_init(SMfsm_fsm_t* const me, const SMfsm_p_statHndlr_t p_statHndlr) {
assert((NULL != me) &&
(NULL != p_statHndlr));

me->p_statHndlr = p_statHndlr;
me->p_statHndlr = p_statHndlr; /* Change to init. state without any exec. */
}

bool SMfsm_sendEvt(SMfsm_fsm_t* const me, const uint8_t evt) {
/* Sanity check (Design by Contract) */
assert((NULL != me) &&
(NULL != me->p_statHndlr));

return ((*me->p_statHndlr)(me, evt));
return ((*me->p_statHndlr)(me, evt)); /* Let current state handle event */
}

SMfsm_p_statHndlr_t SMfsm_getStat(const SMfsm_fsm_t* const me) {
Expand All @@ -34,7 +34,9 @@ void SMfsm_trans(SMfsm_fsm_t* const me, const SMfsm_p_statHndlr_t p_statHndlr) {
(NULL != me->p_statHndlr) &&
(NULL != p_statHndlr));

(void)SMfsm_sendEvt(me, SMFSM_EXIT);
me->p_statHndlr = p_statHndlr;
(void)SMfsm_sendEvt(me, SMFSM_ENTRY);
/* Trans. activity can only be exec. from state handler *before* trans. */

(void)SMfsm_sendEvt(me, SMFSM_EXIT); /* Exec. exit activity of old state */
me->p_statHndlr = p_statHndlr; /* Change state */
(void)SMfsm_sendEvt(me, SMFSM_ENTRY); /* Exec. entry activity of new state */
}
68 changes: 64 additions & 4 deletions src/SMfsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,91 @@
#include "stdbool.h"
#include "assert.h" /* For sanity checks (Design by Contract) */

/** \brief Pre-defined state machine events */
enum SMfsm_evt {
SMFSM_ENTRY = 0,
SMFSM_EXIT,
SMFSM_APP_EVT_START
SMFSM_APP_EVT_START /**< \brief user-defined events start here */
};

typedef struct SMfsm_fsm SMfsm_fsm_t; /* Forward decl. due to circular dep. */
typedef struct SMfsm_fsm SMfsm_fsm_t; /**< \brief Forward decl. due to circular
dep. */

/**
* \biref State handler function pointer type
*
* Functions of this type indicate state of FSM and implement actual FSM
* behaviour in application layer.
* Each such function represents a state which handles events by use of
* `switch (...)` statement. Trans. guards can be implemented by use of `if
* (...)` statements within a `switch (...)` case, that handle conditional
* trans.
* State handler functions with this signature *must* be reentrant.
*/
typedef bool (*SMfsm_p_statHndlr_t)(SMfsm_fsm_t* const me, const uint8_t evt);
/* State handler functions with this signature must be reentrant */

/**
* \brief FSM base object type ("class")
*
* Holds current state (as state handler function) of a FSM.
* Base class can be derived from in application layer by user to add extended
* state variables.
* A derived class is simply another struct with this struct as its first
* member, called "base".
*/
struct SMfsm_fsm {
SMfsm_p_statHndlr_t p_statHndlr;
SMfsm_p_statHndlr_t p_statHndlr; /**< Current state of FSM */
};

/* OPERATIONS
* ==========
*/

/**
* \brief Initialize FSM
*
* \param me Pointer to FSM object
* \param p_statHndlr State handler function pointer (indicating init. state)
*/
void SMfsm_init(SMfsm_fsm_t* const me, const SMfsm_p_statHndlr_t p_statHndlr);

/**
* \brief Send event to FSM
*
* The sent event is directly (synchronously) "digested" by FSM.
*
* \param me Pointer to FSM object
* \param evt Event to send to FSM (implemented as `enum`s)
*
* \return Indicator whether event was handled (`true`) or ignored (`false`)
*/
bool SMfsm_sendEvt(SMfsm_fsm_t* const me, const uint8_t evt);

/**
* \brief Query current state of FSM
*
* \param me Pointer to FSM object
*
* \return State handler function pointer (indicating state)
*/
SMfsm_p_statHndlr_t SMfsm_getStat(const SMfsm_fsm_t* const me);

/**
* \brief Initiate FSM state transition
*
* Handles state trans. procedure as follows (according to UML semantics):
*
* * Exec. exit activity of old state (implemented in appl. layer by user)
* * Change from old to new state of FSM
* * Exec. entry activity of new state (implemented in appl. layer by user)
*
* Trans. activity can be implemented in application layer by user but is only
* exec. from state handler *before* trans., i.e. before state exit, which is
* not compliant with UML semantics.
*
* \param me Pointer to FSM object
* \param p_statHndlr State handler function pointer (indicating target state)
*/
void SMfsm_trans(SMfsm_fsm_t* const me, const SMfsm_p_statHndlr_t p_statHndlr);

#endif /* SMFSM_H */
5 changes: 5 additions & 0 deletions test/support/SMactivity.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
* ==========
*/

/**
* \{
* \brief Function mocks to assert expected calls
*/
void SMactivity_ignore(void);
void SMactivity_entry(void);
void SMactivity_exit(void);
void SMactivity_transInit(void);
void SMactivity_trans(void);
/** \} */

#endif /* SMACTIVITY_H */
32 changes: 21 additions & 11 deletions test/support/SMstatHndlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

#include "SMactivity.h"

/* New FSM structure with extended state variable; derived from base class */
/**
* \brief New FSM structure with extended state variable; derived from base
* class
*/
typedef struct {
SMfsm_fsm_t base; /* Base class */
bool grd1; /* Extended state variable */
SMfsm_fsm_t base; /**< \brief Base class */
bool grd1; /**< \brief Extended state variable */
} SMstatHndlr_fsm_t;

/* ATTRIBUTES
Expand Down Expand Up @@ -144,17 +147,18 @@ bool SMstatHndlr_statC(SMfsm_fsm_t* const me, const uint8_t evt) {
break;
}
case SMSTATHNDLR_EVT_B: {
if (false == pv_grd0) {
/* Trans. guard */
if (false == pv_grd0) { /* Guard condition false? */
SMactivity_trans();
SMfsm_trans(me, &SMstatHndlr_statC);
SMfsm_trans(me, &SMstatHndlr_statC); /* Trans. to self */
evtHandled = true;
}
else if (true == pv_grd0) {
else if (true == pv_grd0) { /* Guard condition true? */
SMactivity_trans();
SMfsm_trans(me, &SMstatHndlr_statB);
evtHandled = true;
}
else {;} /* Do nothing */
else {;} /* Do nothing (MISRA-required) */
break;
}
case SMSTATHNDLR_EVT_C: {
Expand All @@ -170,6 +174,8 @@ bool SMstatHndlr_statC(SMfsm_fsm_t* const me, const uint8_t evt) {
return (evtHandled);
}

/* Only used to demonstrate utilization of extended state variables via
inheritance */
bool SMstatHndlr_statZ(SMfsm_fsm_t* const me, const uint8_t evt) {
bool evtHandled = false;

Expand All @@ -185,15 +191,16 @@ bool SMstatHndlr_statZ(SMfsm_fsm_t* const me, const uint8_t evt) {
break;
}
case SMSTATHNDLR_EVT_Z: {
/* Explicit type downcast needed (safe as long as `me` input
/* Trans. guard:
Explicit type downcast needed (safe as long as `me` input
argument always points to derived class instance).
In other words, this state handler function must only be used
with `me` pointers of type `SMstatHndlr_fsm_t*` (derived class)
and never `SMfsm_fsm_t` (base class), as the function’s
signature might suggests. */
if (true == ((SMstatHndlr_fsm_t*)me)->grd1) {
signature might suggest. */
if (true == ((SMstatHndlr_fsm_t*)me)->grd1) { /* Guard cond. true? */
SMactivity_trans();
SMfsm_trans(me, &SMstatHndlr_statZ);
SMfsm_trans(me, &SMstatHndlr_statZ); /* Trans. to self */
evtHandled = true;
}
break;
Expand All @@ -206,6 +213,9 @@ bool SMstatHndlr_statZ(SMfsm_fsm_t* const me, const uint8_t evt) {
return (evtHandled);
}

/* FSM object contructor functions
*/

void SMstatHndlr_fsmCtor(void) {
SMfsm_init(&pv_fsm, &statInit);
}
Expand Down
29 changes: 21 additions & 8 deletions test/support/SMstatHndlr.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "SMfsm.h"

/** \brief User-defined state machine events */
enum SMstatHndlr_evt {
SMSTATHNDLR_EVT_A = SMFSM_APP_EVT_START,
SMSTATHNDLR_EVT_B,
Expand All @@ -19,33 +20,45 @@ enum SMstatHndlr_evt {
* ==========
*/

/* Global opaque pointers to FSM objects */
/**
* \{
* \brief Global opaque pointers to FSM objects
*/
extern SMfsm_fsm_t* const SMstatHndlr_p_fsm;
extern SMfsm_fsm_t* const SMstatHndlr_p_fsmZ;
/** \} */

/* OPERATIONS
* ==========
*/

/* Extended state variable access operation */
/** \brief Set extended state variable */
void SMstatHndlr_setGrd0(const bool grd);

/* State handler functions
/**
* \{
* \brief State handler functions
*
* The implementation of the state handler functions defines the state machine
* configuration (i.e. the state topology).
* Implementation of state handler functions defines state machine
* configuration (i.e. state topology).
*/
bool SMstatHndlr_statA(SMfsm_fsm_t* const me, const uint8_t evt);
bool SMstatHndlr_statB(SMfsm_fsm_t* const me, const uint8_t evt);
bool SMstatHndlr_statC(SMfsm_fsm_t* const me, const uint8_t evt);
/** \} */

/* State handler function that uses extended state variable `grd1`; derived
* from `SMfsm_fsm_t` base class
/**
* \brief State handler function that uses extended state variable `grd1`;
* derived from `SMfsm_fsm_t` base class
*/
bool SMstatHndlr_statZ(SMfsm_fsm_t* const me, const uint8_t evt);

/* Constructors of FSM objects */
/**
* \{
* \brief Constructors of FSM objects
*/
void SMstatHndlr_fsmCtor(void);
void SMstatHndlr_fsmZCtor(void);
/** \} */

#endif /* SMSTATHNDLR_H */
Loading

0 comments on commit b67677b

Please sign in to comment.