@@ -18,10 +18,11 @@ State Creation
18
18
19
19
A state is represented by three functions, where one function implements the
20
20
Entry actions, another function implements the Run actions, and the last
21
- function implements the Exit actions. The prototype for these functions is as
22
- follows: ``void funct(void *obj) ``, where the ``obj `` parameter is a user
23
- defined structure that has the state machine context, :c:struct: `smf_ctx `, as
24
- its first member. For example::
21
+ function implements the Exit actions. The prototype for the entry and exit
22
+ functions are as follows: ``void funct(void *obj) ``, and the prototype for the
23
+ run action is ``enum smf_state_result funct(void *obj) `` where the ``obj ``
24
+ parameter is a user defined structure that has the state machine context,
25
+ :c:struct: `smf_ctx `, as its first member. For example::
25
26
26
27
struct user_object {
27
28
struct smf_ctx ctx;
@@ -39,6 +40,16 @@ By default, a state can have no ancestor states, resulting in a flat state
39
40
machine. But to enable the creation of a hierarchical state machine, the
40
41
:kconfig:option: `CONFIG_SMF_ANCESTOR_SUPPORT ` option must be enabled.
41
42
43
+ The return value of the run action, :c:enum: `smf_state_result ` determines if the
44
+ state machine propagates the event to parent run actions
45
+ (:c:enum: `SMF_EVENT_PROPAGATE `) or if the event was handled by the run action
46
+ (:c:enum: `SMF_EVENT_HANDLED `). Flat state machines do not have parent actions,
47
+ so the return code is ignored; returning :c:enum: `SMF_EVENT_HANDLED ` is
48
+ recommended.
49
+
50
+ Calling :c:func: `smf_set_state ` prevents calling parent run
51
+ actions, even if :c:enum: `SMF_EVENT_PROPAGATE ` is returned.
52
+
42
53
By default, the hierarchical state machines do not support initial transitions
43
54
to child states on entering a superstate. To enable them the
44
55
:kconfig:option: `CONFIG_SMF_INITIAL_TRANSITION ` option must be enabled.
@@ -111,13 +122,6 @@ To run the state machine, the :c:func:`smf_run_state` function should be
111
122
called in some application dependent way. An application should cease calling
112
123
smf_run_state if it returns a non-zero value.
113
124
114
- Preventing Parent Run Actions
115
- =============================
116
-
117
- Calling :c:func: `smf_set_handled ` prevents calling the run action of parent
118
- states. It is not required to call :c:func: `smf_set_handled ` if the state
119
- calls :c:func: `smf_set_state `.
120
-
121
125
State Machine Termination
122
126
=========================
123
127
@@ -197,19 +201,21 @@ Code::
197
201
{
198
202
/* Do something */
199
203
}
200
- static void s0_run(void *o)
204
+ static enum smf_state_result s0_run(void *o)
201
205
{
202
206
smf_set_state(SMF_CTX(&s_obj), &demo_states[S1]);
207
+ return SMF_EVENT_HANDLED;
203
208
}
204
209
static void s0_exit(void *o)
205
210
{
206
211
/* Do something */
207
212
}
208
213
209
214
/* State S1 */
210
- static void s1_run(void *o)
215
+ static enum smf_state_result s1_run(void *o)
211
216
{
212
217
smf_set_state(SMF_CTX(&s_obj), &demo_states[S2]);
218
+ return SMF_EVENT_HANDLED;
213
219
}
214
220
static void s1_exit(void *o)
215
221
{
@@ -221,9 +227,10 @@ Code::
221
227
{
222
228
/* Do something */
223
229
}
224
- static void s2_run(void *o)
230
+ static enum smf_state_result s2_run(void *o)
225
231
{
226
232
smf_set_state(SMF_CTX(&s_obj), &demo_states[S0]);
233
+ return SMF_EVENT_HANDLED;
227
234
}
228
235
229
236
/* Populate state table */
@@ -311,21 +318,24 @@ Code::
311
318
}
312
319
313
320
/* State S0 */
314
- static void s0_run(void *o)
321
+ static enum smf_state_result s0_run(void *o)
315
322
{
316
323
smf_set_state(SMF_CTX(&s_obj), &demo_states[S1]);
324
+ return SMF_EVENT_HANDLED;
317
325
}
318
326
319
327
/* State S1 */
320
- static void s1_run(void *o)
328
+ static enum smf_state_result s1_run(void *o)
321
329
{
322
330
smf_set_state(SMF_CTX(&s_obj), &demo_states[S2]);
331
+ return SMF_EVENT_HANDLED;
323
332
}
324
333
325
334
/* State S2 */
326
- static void s2_run(void *o)
335
+ static enum smf_state_result s2_run(void *o)
327
336
{
328
337
smf_set_state(SMF_CTX(&s_obj), &demo_states[S0]);
338
+ return SMF_EVENT_HANDLED;
329
339
}
330
340
331
341
/* Populate state table */
@@ -369,7 +379,7 @@ When designing hierarchical state machines, the following should be considered:
369
379
state. For example, the s1_exit function is called before the parent_exit
370
380
function is called.
371
381
- The parent_run function only executes if the child_run function does not
372
- call either :c:func: `smf_set_state ` or :c:func: ` smf_set_handled `.
382
+ call either :c:func: `smf_set_state ` or return :c:enum: ` SMF_EVENT_HANDLED `.
373
383
374
384
Event Driven State Machine Example
375
385
**********************************
@@ -439,6 +449,7 @@ Code::
439
449
if (s->events & EVENT_BTN_PRESS) {
440
450
smf_set_state(SMF_CTX(&s_obj), &demo_states[S1]);
441
451
}
452
+ return SMF_EVENT_HANDLED;
442
453
}
443
454
444
455
/* State S1 */
@@ -455,6 +466,7 @@ Code::
455
466
if (s->events & EVENT_BTN_PRESS) {
456
467
smf_set_state(SMF_CTX(&s_obj), &demo_states[S0]);
457
468
}
469
+ return SMF_EVENT_HANDLED;
458
470
}
459
471
460
472
/* Populate state table */
0 commit comments