From 3367846efe1399c2e6b4f64dfe1038e81fc10ad1 Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Thu, 1 Jan 2026 21:02:36 -0300 Subject: [PATCH] docs/applications/smf: added state machine framework example documentation Update Doc - WIP SFM doc updated - WIP Finished first documentation release Update documentation after source code changes Signed-off-by: Felipe Moura --- .../applications/examples/smf/index.rst | 59 ++ .../smf/images/Flat-state-machine-diagram.png | Bin 0 -> 21645 bytes .../Hierarchical-state-machine-diagram.png | Bin 0 -> 32344 bytes .../applications/system/smf/index.rst | 570 ++++++++++++++++++ 4 files changed, 629 insertions(+) create mode 100644 Documentation/applications/examples/smf/index.rst create mode 100644 Documentation/applications/system/smf/images/Flat-state-machine-diagram.png create mode 100644 Documentation/applications/system/smf/images/Hierarchical-state-machine-diagram.png create mode 100644 Documentation/applications/system/smf/index.rst diff --git a/Documentation/applications/examples/smf/index.rst b/Documentation/applications/examples/smf/index.rst new file mode 100644 index 0000000000000..006a92ad0921f --- /dev/null +++ b/Documentation/applications/examples/smf/index.rst @@ -0,0 +1,59 @@ +================================================== +``smf`` State Machine Framework HSM PSiCC2 Example +================================================== + +This example implements an event-driven hierarchical state machine using the +State Machine Framework (SMF). It reproduces the statechart shown in Figure 2.11 +of Practical UML Statecharts in C/C++, 2nd Edition, by Miro Samek (PSiCC2). +The ebook is available at https://www.state-machine.com/psicc2. + +For each state, the entry, run, and exit actions are logged to the console, as +well as logging when a state handles an event or explicitly ignores it and +passes it up to the parent state. + +It should be possible to build and run this demo on most boards or emulators +that support NSH, SMF, and message queues. + +Configuration +============= + +- ``CONFIG_EXAMPLES_SMF`` – Enables the SMF PSiCC2 demo. +- ``CONFIG_NSH_BUILTIN_APPS`` – Build the demo as an NSH built-in application. +- ``CONFIG_SYSTEM_SMF`` – Enable the State Machine Framework support. +- ``CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT`` – Enable ancestor/parent state support. +- ``CONFIG_SYSTEM_SMF_INITIAL_TRANSITION`` – Enable initial transition support. +- ``CONFIG_DISABLE_MQUEUE=n`` – Message queue support must be available. +- ``CONFIG_EXAMPLES_SMF_PROGNAME`` – Program name, default ``hsm_psicc2``. +- ``CONFIG_EXAMPLES_SMF_PRIORITY`` – Priority of the SMF task, default ``100``. +- ``CONFIG_EXAMPLES_SMF_STACKSIZE`` – Stack size of the SMF task, default + ``2048``. +- ``CONFIG_EXAMPLES_SMF_QUEUE_SIZE`` – Size of the message queue, default ``10``. +- ``CONFIG_EXAMPLES_SMF_MQ_NAME`` – Name of the message queue, default + ``/hsm_psicc2_mq``. + +Usage +===== + +The demo registers the ``hsm_psicc2`` NSH command (configurable via +``CONFIG_EXAMPLES_SMF_PROGNAME``): + +.. code-block:: bash + + hsm_psicc2 start + hsm_psicc2 event + hsm_psicc2 terminate + +- ``start`` spawns the state machine thread and initializes the SMF context. +- ``event `` sends events A through I to the state machine (PSiCC2 + Figure 2.11). +- ``terminate`` stops the state machine thread; there is no way to restart it + and further events are not processed. + +Comparison to PSiCC2 Output +=========================== + +Not all transitions modeled in UML may be supported by the State Machine +Framework. Unsupported transitions may lead to results different from the +example run in PSiCC2 Section 2.3.15. The differences are not listed here since +it is hoped SMF will support these transitions in the future and the list would +become outdated. diff --git a/Documentation/applications/system/smf/images/Flat-state-machine-diagram.png b/Documentation/applications/system/smf/images/Flat-state-machine-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..3c06c82b6a62b856ffc40d45b4039a07538967c7 GIT binary patch literal 21645 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 aUu0jOWRnkQ?4JeuFn`~G53X)u=KKu?G!0<@ literal 0 HcmV?d00001 diff --git a/Documentation/applications/system/smf/images/Hierarchical-state-machine-diagram.png b/Documentation/applications/system/smf/images/Hierarchical-state-machine-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..99310a1de5f929ac902b84fa78e46d3d8743d474 GIT binary patch literal 32344 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 + + /* Forward declaration of state table */ + static const struct smf_state demo_states[]; + + /* List of demo states */ + enum demo_state + { + STATE_IDLE, + STATE_ACTIVE, + STATE_ERROR, + }; + + /* User defined object */ + struct s_object { + /* This must be first */ + struct smf_ctx ctx; + + /* Other state specific data add here */ + } s_obj; + + /* State idle */ + static void idle_entry(void *o) + { + /* Do something */ + } + + static enum smf_state_result idle_run(void *o) + { + smf_set_state(SMF_CTX(&s_obj), &demo_states[STATE_ACTIVE]); + return SMF_EVENT_HANDLED; + } + + static void idle_exit(void *o) + { + /* Do something */ + } + + /* State active */ + static void active_entry(void *o) + { + /* Do something */ + } + + static enum smf_state_result active_run(void *o) + { + smf_set_state(SMF_CTX(&s_obj), &demo_states[STATE_ERROR]); + return SMF_EVENT_HANDLED; + } + + static void active_exit(void *o) + { + /* Do something */ + } + + /* State error */ + static void error_entry(void *o) + { + /* Do something */ + } + + static enum smf_state_result error_run(void *o) + { + smf_set_state(SMF_CTX(&s_obj), &demo_states[STATE_IDLE]); + return SMF_EVENT_HANDLED; + } + + static void error_exit(void *o) + { + /* Do something */ + } + + /* Populate state table */ + static const struct smf_state demo_states[] = { + [STATE_IDLE] = SMF_CREATE_STATE(idle_entry, idle_run, idle_exit, NULL, NULL), + /* State ACTIVE does not have an entry action */ + [STATE_ACTIVE] = SMF_CREATE_STATE(NULL, active_run, active_exit, NULL, NULL), + /* State ERROR does not have an exit action */ + [STATE_ERROR] = SMF_CREATE_STATE(error_entry, error_run, NULL, NULL, NULL), + }; + + int main(void) + { + int32_t ret; + + /* Set initial state */ + smf_set_initial(SMF_CTX(&s_obj), &demo_states[STATE_IDLE]); + + /* Run the state machine */ + while(1) { + /* State machine terminates if a non-zero value is returned */ + ret = smf_run_state(SMF_CTX(&s_obj)); + if (ret) { + /* handle return code and terminate state machine */ + break; + } + sleep(1); + } + } + +Hierarchical State Machine (HSM) +-------------------------------- + +When ``CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT`` is enabled, states may define a parent. +The example below turns the following state diagram into code using SMF, where IDLE and ACTIVE share a parent +state and IDLE is the initial state. + +.. figure:: images/Hierarchical-state-machine-diagram.png + :alt: Hierarchical State Machine Diagram + :align: center + :width: 40% + + Hierarchical state machine example implemented using SMF. + +Code + +.. code-block:: c + + #include + + /* Forward declaration of state table */ + static const struct smf_state demo_states[]; + + /* List of demo states */ + enum demo_state { PARENT, IDLE, ACTIVE, ERROR }; + + /* User defined object */ + struct s_object { + /* This must be first */ + struct smf_ctx ctx; + + /* Other state specific data add here */ + } s_obj; + + /* Parent State */ + static void parent_entry(void *o) + { + /* Do something */ + } + static void parent_exit(void *o) + { + /* Do something */ + } + + /* State IDLE */ + static enum smf_state_result idle_run(void *o) + { + smf_set_state(SMF_CTX(&s_obj), &demo_states[ACTIVE]); + return SMF_EVENT_HANDLED; + } + + /* State ACTIVE */ + static enum smf_state_result active_run(void *o) + { + smf_set_state(SMF_CTX(&s_obj), &demo_states[ERROR]); + return SMF_EVENT_HANDLED; + } + + /* State ERROR */ + static enum smf_state_result error_run(void *o) + { + smf_set_state(SMF_CTX(&s_obj), &demo_states[IDLE]); + return SMF_EVENT_HANDLED; + } + + /* Populate state table */ + static const struct smf_state demo_states[] = { + /* Parent state does not have a run action */ + [PARENT] = SMF_CREATE_STATE(parent_entry, NULL, parent_exit, NULL, NULL), + /* Child states do not have entry or exit actions */ + [IDLE] = SMF_CREATE_STATE(NULL, idle_run, NULL, &demo_states[PARENT], NULL), + [ACTIVE] = SMF_CREATE_STATE(NULL, active_run, NULL, &demo_states[PARENT], NULL), + /* State ERROR do not have entry or exit actions and no parent */ + [ERROR] = SMF_CREATE_STATE(NULL, error_run, NULL, NULL, NULL), + }; + + int main(void) + { + int32_t ret; + + /* Set initial state */ + smf_set_initial(SMF_CTX(&s_obj), &demo_states[IDLE]); + + /* Run the state machine */ + while(1) { + /* State machine terminates if a non-zero value is returned */ + ret = smf_run_state(SMF_CTX(&s_obj)); + if (ret) { + /* handle return code and terminate state machine */ + break; + } + sleep(1); + } + } + +When designing hierarchical state machines, the following should be considered: + +- Ancestor entry actions are executed before the sibling entry actions. For example, + the parent_entry function is called before the ``idle_entry`` function. + +- Transitioning from one sibling to another with a shared ancestry does not re-execute the ancestor's entry + action or execute the exit action. For example, the parent_entry function is not called when transitioning + from IDLE to ACTIVE, nor is the parent_exit function called. + +- Ancestor exit actions are executed after the exit action of the current state. + For example, the idle_exit function is called before the parent_exit function is called. + +- The parent_run function only executes if the child_run function does not call either ``smf_set_state()`` + or return ``SMF_EVENT_HANDLED``. + +- Avoid malformed hierarchical state machines by ensuring the state always transitions to a leaf state when + ``CONFIG_SYSTEM_SMF_INITIAL_TRANSITION`` is not enabled, or when a parent state's initial state is undefined. + +Initial Transitions +=================== + +If ``CONFIG_SYSTEM_SMF_INITIAL_TRANSITION`` is enabled, a parent state may define an +initial child state. + +.. code-block:: c + + static const struct smf_state demo_states[] = + { + [STATE_PARENT] = SMF_CREATE_STATE(parent_entry, NULL, parent_exit, NULL, &demo_states[STATE_CHILD_A]), + [STATE_CHILD_A] = SMF_CREATE_STATE(NULL, child_a_run, NULL, &demo_states[STATE_PARENT], NULL), + }; + +When entering ``STATE_PARENT``, the framework automatically transitions to +``STATE_CHILD_A``. + +.. note:: + + Without initial transition support enabled, applications must always + transition directly to a leaf state. + +State Execution Model +===================== + +The application controls execution explicitly. + +1. Set the initial state using ``smf_set_initial()`` +2. Call ``smf_run_state()`` from an event loop +3. Stop execution when a non-zero value is returned + +.. code-block:: c + + smf_set_initial(SMF_CTX(&app), &demo_states[STATE_IDLE]); + + while (1) + { + int32_t rc = smf_run_state(SMF_CTX(&app)); + if (rc != 0) + { + break; + } + + /* Block, poll, or wait for an event */ + } + +State Run Semantics +------------------- + +The run action returns: + +- ``SMF_EVENT_HANDLED`` – event consumed +- ``SMF_EVENT_PROPAGATE`` – propagate to parent (HSM only) + +If ``smf_set_state()`` is called, propagation stops immediately. + +State Transitions +================= + +Transitions are requested explicitly by calling ``smf_set_state()`` from +entry or run actions. + +.. code-block:: c + + static enum smf_state_result active_run(void *obj) + { + struct s_object *s = (struct s_object *)obj; + + if (s->error) + { + smf_set_state(SMF_CTX(s), &demo_states[STATE_ERROR]); + return SMF_EVENT_HANDLED; + } + + return SMF_EVENT_HANDLED; + } + +Calling ``smf_set_state()`` from exit actions is rejected by design. + +Termination +=========== + +To terminate a state machine, call ``smf_set_terminate()``. + +.. code-block:: c + + smf_set_terminate(SMF_CTX(&app), -ECANCELED); + +The value passed is returned by ``smf_run_state()`` and can be used to signal +the termination reason. + +State Introspection +=================== + +SMF exposes two helper APIs: + +- ``smf_get_current_leaf_state()`` +- ``smf_get_current_executing_state()`` + +These functions are primarily intended for diagnostics, logging, and testing. + +UML Compliance +============== + +SMF follows UML hierarchical state machine semantics: + +- Entry/exit actions execute according to the least common ancestor (LCA) +- Self-transitions execute full exit/entry sequences +- Local transitions are supported implicitly + +Differences from UML: + +1. Transition actions execute in the source state context +2. Only external self-transitions are supported +3. No explicit terminate pseudostate + +Notes and Constraints +===================== + +- SMF performs no dynamic allocation +- State tables are typically ``static const`` +- Thread safety is the responsibility of the application +- One SMF instance represents one execution region +- Orthogonal regions require multiple SMF instances + +Configuration Options +===================== + +- ``CONFIG_SYSTEM_SMF`` +- ``CONFIG_SYSTEM_SMF_ANCESTOR_SUPPORT`` +- ``CONFIG_SYSTEM_SMF_INITIAL_TRANSITION`` + +Code Location +============= + +- ``apps/system/smf`` – Framework implementation +- ``apps/include/system/smf.h`` – Public API