- \ref fsm_general
- \ref state_functions
- \ref fsm_events
+- \ref fsm_usage
- \ref subfsm
\section fsm_general Introduction
or by some other piece of code. Every FSM is defined by structure
::robo_fsm and a set of state functions. There is exactly one
"current" state function at a given time. The goal of the current state
-functions is to react to the events. The reaction to the event can be
+functions is to react to events. The reaction to an event can be
represented by an arbitrary piece of code that does something
useful. It is also possible to change the current state (function) of
FSM (so called state transition). Having several state functions, it
is the identifier of the event (see section \ref fsm_events) to be
handled. In the handling code you can execute whatever you want. If
there is some data associated with the event, it can be retrieved by
-FSM_EVENT_PTR() or FSM_EVENT_INT(). Additionally, FSM infrastructure
+#FSM_EVENT_PTR or #FSM_EVENT_INT. Additionally, FSM infrastructure
provides some useful functions and macros. To work with time, you can
use FSM_TIMER(). To execute transition to another state, use
FSM_TRANSITION() or SUBFSM_TRANSITION() (see \ref subfsm). To send an
\endcode
For the above to work, it is important to declare the macro @c FSM_<id>
-before including header with event definition and fsm.h. See \ref
-fsm_events.
+before including header with event definition and fsm.h. See the note in \ref
+fsm_events section. This means, that state functions for different
+FSMs have to be declared in separate files.
\section fsm_events Events
These requirements are hard to achieve in plain C. Therefore,
additional events for FSMs are declared as a data structure in Python
-and there is a Python script, which converts this definition to .h a
+and there is a Python script eventgen.py, which converts this definition to .h a
.c files.
-The event definition (for example see roboevent.py) is a Python
-dictionary (associative array) called @c events. Keys to this dictionary
-are the lowercase identifiers of FSM. The value is another dictionary,
-which defines the events for that FSM. The key is the event identifier and
-value is a comment.
+The event definition is a Python dictionary (associative array) called
+@c events. Keys to this dictionary are the lowercase identifiers of
+FSM. The value is another dictionary, which defines the events for
+that FSM. The key is the event identifier and value is a comment. In
+the example below, event for two FSMs called "tested" and "tester" are
+defined. The "tested" FSM can handle additional events EV_PING and EV_OTHER and
+"tester" FSM handles "EV_PONG".
+
+\include example_ev.py
The script, which generates .c and .h source code is called
eventgen.py. In .h, there is one enum for each FSM with all events
not handled in switch statement (unless you use @c default statement).
@note You have to always include the generated header file with events before fsm.h.
+If you do not do so, an error is generated.
@note In the source, where you define your state function, you have to
define macro @c FSM_<id>, where @c <id> is uppercase identifier of FSM
-as defined in event definition.
+as defined in event definition. If you do not do so, you get a compilation error
+on definition of state function. GCC generates this error message:
+@verbatim
+error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘FSM_XXX_not_defined’
+@endverbatim
+
+\section fsm_usage Usage
+
+To use FSMs provided by this library in your application, you need to
+-# define additional event for your automatons (see section \ref fsm_events),
+-# define state functions for your automatons (see section \ref
+state_functions) and
+-# start execution of the automatons (every FSM executes in its own thread).
+
+Definition of state functions usually starts with lines like this:
+@code
+#define FSM_SOME_NAME // define which FSM state functions are to be declared here
+#include "events.h" // include definition of additional events (generated from events.py)
+#include <fsm.h>
+
+FSM_STATE(test_state1) {
+ ...
+}
+@endcode
+
+Starting the execution of the automaton usually looks like:
+@code
+struct robo_fsm fsm;
+fsm_init(&fsm, "id_for_debug_massages");
+fsm.state = &fsm_state_test_state1; // Initial state of the automaton
+if (fsm_start(&fsm, NULL) != 0) {
+ perror("fsm_start");
+ exit(1);
+}
+@endcode
\section subfsm Sub-Automatons