-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSMfsm.h
100 lines (88 loc) · 3.04 KB
/
SMfsm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** \file */
#ifndef SMFSM_H
#define SMFSM_H
/* `"` used intentionally. This allows the user to override and provide his
own implementation before falling back to libc. */
#include "stdint.h"
#include "stddef.h"
#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 /**< \brief user-defined events start here */
};
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);
/**
* \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; /**< 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 */