forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
smf.h
154 lines (136 loc) · 4.09 KB
/
smf.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Copyright 2021 The Chromium OS Authors
*
* SPDX-License-Identifier: Apache-2.0
*/
/* State Machine Framework */
#ifndef ZEPHYR_INCLUDE_SMF_H_
#define ZEPHYR_INCLUDE_SMF_H_
#ifdef CONFIG_SMF_ANCESTOR_SUPPORT
/**
* @brief Macro to create a hierarchical state.
*
* @param _entry State entry function
* @param _run State run function
* @param _exit State exit function
* @param _parent State parent object or NULL
*/
#define SMF_CREATE_STATE(_entry, _run, _exit, _parent) \
{ \
.entry = _entry, \
.run = _run, \
.exit = _exit, \
.parent = _parent \
}
#else
/**
* @brief Macro to create a flat state.
*
* @param _entry State entry function
* @param _run State run function
* @param _exit State exit function
*/
#define SMF_CREATE_STATE(_entry, _run, _exit) \
{ \
.entry = _entry, \
.run = _run, \
.exit = _exit \
}
#endif /* CONFIG_SMF_ANCESTOR_SUPPORT */
/**
* @brief Macro to cast user defined object to state machine
* context.
*
* @param o A pointer to the user defined object
*/
#define SMF_CTX(o) ((struct smf_ctx *)o)
#ifdef __cplusplus
extern "C" {
#endif
#include <zephyr.h>
/**
* @brief Function pointer that implements a portion of a state
*
* @param obj pointer user defined object
*/
typedef void (*state_execution)(void *obj);
/** General state that can be used in multiple state machines. */
struct smf_state {
/** Optional method that will be run when this state is entered */
const state_execution entry;
/**
* Optional method that will be run repeatedly during state machine
* loop.
*/
const state_execution run;
/** Optional method that will be run when this state exists */
const state_execution exit;
/**
* Optional parent state that contains common entry/run/exit
* implementation among various child states.
* entry: Parent function executes BEFORE child function.
* run: Parent function executes AFTER child function.
* exit: Parent function executes AFTER child function.
*
* Note: When transitioning between two child states with a shared parent,
* that parent's exit and entry functions do not execute.
*/
const struct smf_state *parent;
};
/** Defines the current context of the state machine. */
struct smf_ctx {
/** Current state the state machine is executing. */
const struct smf_state *current;
/** Previous state the state machine executed */
const struct smf_state *previous;
/**
* This value is set by the set_terminate function and
* should terminate the state machine when its set to a
* value other than zero when it's returned by the
* run_state function.
*/
int32_t terminate_val;
/**
* The state machine casts this to a "struct internal_ctx" and it's
* used to track state machine context
*/
uint32_t internal;
};
/**
* @brief Initializes the state machine and sets its initial state.
*
* @param ctx State machine context
* @param init_state Initial state the state machine starts in.
*/
void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state);
/**
* @brief Changes a state machines state. This handles exiting the previous
* state and entering the target state. A common parent state will not
* exited nor be re-entered.
*
* @param ctx State machine context
* @param new_state State to transition to (NULL is valid and exits all states)
*/
void smf_set_state(struct smf_ctx *ctx, const struct smf_state *new_state);
/**
* @brief Terminate a state machine
*
* @param ctx State machine context
* @param val Non-Zero termination value that's returned by the smf_run_state
* function.
*/
void smf_set_terminate(struct smf_ctx *ctx, int32_t val);
/**
* @brief Runs one iteration of a state machine (including any parent states)
*
* @param ctx State machine context
* @return A non-zero value should terminate the state machine. This
* non-zero value could represent a terminal state being reached
* or the detection of an error that should result in the
* termination of the state machine.
*/
int32_t smf_run_state(struct smf_ctx *ctx);
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_SMF_H_ */