summaryrefslogtreecommitdiff
path: root/digital/ai
diff options
context:
space:
mode:
authorJerome Jutteau2013-03-05 19:48:42 +0100
committerJerome Jutteau2013-03-17 15:10:13 +0100
commitdee86bd16eba1a6e80292da346964703bca3c134 (patch)
tree24592d1258b84c16d4011f300ae6b5c6e9a6c6f0 /digital/ai
parent8f7c312ad1fe132c5279a0f5d0101834acf5857d (diff)
digital/ai/src/fsm: new return system
Diffstat (limited to 'digital/ai')
-rw-r--r--digital/ai/src/fsm/Makefile.fsm8
-rw-r--r--digital/ai/src/fsm/angfsm.h21
-rw-r--r--digital/ai/src/fsm/angfsm.host.c1226
-rw-r--r--digital/ai/src/fsm/angfsm_generic.h54
-rw-r--r--digital/ai/src/fsm/angfsm_host_exec.h145
-rw-r--r--digital/ai/src/fsm/angfsm_renaming.h15
-rw-r--r--digital/ai/src/fsm/init.c20
7 files changed, 939 insertions, 550 deletions
diff --git a/digital/ai/src/fsm/Makefile.fsm b/digital/ai/src/fsm/Makefile.fsm
index 97363bbd..310a4925 100644
--- a/digital/ai/src/fsm/Makefile.fsm
+++ b/digital/ai/src/fsm/Makefile.fsm
@@ -1,12 +1,12 @@
fsm_AI_gen.avr.c: angfsm_gen_avr_AI.h
dot_AI_1.dot: fsm_AI_gen.h
angfsm_gen_avr_AI.h: io_hub.host
- ./$< --ang-gen avr
+ ./$< --ang-gen avr --ang-dot AI.dot
mv angfsm_gen_avr_AI.c fsm_AI_gen.avr.c
-view: dot_AI_1.view
-png: dot_AI_1.png
-svg: dot_AI_1.svg
+view: AI.view
+png: AI.png
+svg: AI.svg
%.view: %.dot
dot -Txlib $<
diff --git a/digital/ai/src/fsm/angfsm.h b/digital/ai/src/fsm/angfsm.h
index 2934ec4e..12ce101a 100644
--- a/digital/ai/src/fsm/angfsm.h
+++ b/digital/ai/src/fsm/angfsm.h
@@ -1,6 +1,6 @@
/*
AngFSM - Almost Non Generated Finite State Machine
- Copyright 2011, 2012 Jerome Jutteau
+ Copyright 2011-2013 Jerome Jutteau
This file is part of AngFSM.
@@ -36,20 +36,33 @@
ANGFSM_PASTE_EXPAND (a, ANGFSM_PASTE_EXPAND (b, c))
#define FIRST(first, others...) first
+#define IFELSE_ARG1(yes, no, params...) \
+ IFELSE_ARG1_ (params, IFELSE_ARG1_SEQ_(yes, no))
+#define IFELSE_ARG1_(params...) \
+ IFELSE_ARG1__ (params)
+#define IFELSE_ARG1__( _a1, \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \
+ _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
+ selector, ...) selector
+#define IFELSE_ARG1_SEQ_(yes, no) \
+ no, no, no, no, no, no, no, no, no, no, \
+ no, no, no, no, no, no, no, no, no, no, \
+ yes
+
#ifdef __HOST_ARCH__
/* Include generated header. */
-#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_host_, ANGFSM_NAME).h)
#include "angfsm_generic.h"
+#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_host_, ANGFSM_NAME).h)
#elif defined(__AVR_ARCH__)
/* Include generated header. */
-#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_avr_, ANGFSM_NAME).h)
#include "angfsm_generic.h"
+#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_avr_, ANGFSM_NAME).h)
#elif defined(__arm__)
/* Include generated header. */
-#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_arm_, ANGFSM_NAME).h)
#include "angfsm_generic.h"
+#include XSTR (ANGFSM_PASTE_EXPAND (angfsm_gen_arm_, ANGFSM_NAME).h)
#else
/* Compiling for HOST but for direct execution. */
diff --git a/digital/ai/src/fsm/angfsm.host.c b/digital/ai/src/fsm/angfsm.host.c
index fe8f403e..03201bae 100644
--- a/digital/ai/src/fsm/angfsm.host.c
+++ b/digital/ai/src/fsm/angfsm.host.c
@@ -1,6 +1,6 @@
/*
AngFSM - Almost Non Generated Finite State Machine
- Copyright 2011, 2012 Jerome Jutteau
+ Copyright 2011-2013 Jerome Jutteau
This file is part of AngFSM.
@@ -18,8 +18,6 @@
along with AngFSM. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef HOST
-
#include "angfsm.h"
#include <assert.h>
@@ -37,7 +35,7 @@ void
angfsm_build_print_help ()
{
printf (
- "AngFSM Copyright (C) 2011, 2012 Jérôme Jutteau\n"
+ "AngFSM Copyright (C) 2011-2013 Jérôme Jutteau\n"
"This program comes with ABSOLUTELY NO WARRANTY;\n"
"This is free software, and you are welcome to redistribute it\n"
"under certain conditions; consult license for details.\n"
@@ -71,10 +69,10 @@ angfsm_build_print_help ()
" for a selected fsm. Put this option before --ang-gen.\n"
"--ang-no-sanity-check\n"
" Disable sanity check during execution on the selected fsm or on\n"
- " all fsm. Sanity checks are not embedded in generated code."
+ " all fsm. Sanity checks are not embedded in generated code.\n"
"--ang-print-transitions\n"
" Print transition to stdout each time one occurs. Not available for\n"
- " generated code."
+ " generated code.\n"
);
}
@@ -145,10 +143,13 @@ angfsm_build_arg_free (char ***tab, int nb)
}
void
-angfsm_build_print (angfsm_build_t *fsm,
- angfsm_build_trans_t *trans,
- angfsm_build_branch_chain_t *branch)
+angfsm_build_print_trans (angfsm_build_t *fsm,
+ angfsm_build_trans_t *trans,
+ angfsm_build_branch_chain_t *branch)
{
+ assert (fsm);
+ assert (trans);
+ assert (branch);
if (branch->name == NULL)
fprintf (stderr, "Transition: %s -- %s --> %s\n",
trans->state->var_name,
@@ -361,13 +362,6 @@ angfsm_build_sanity_check (angfsm_build_t *fsm)
}
sc = sc->next;
}
-
- /* Sanity check 8: any transition output error ?
- * for example, as we are in state s42, making a angfsm_NEXT (s1, e2) will
- * work but this is a user's mistake.
- *
- * TODO Find a way to check this.
- **/
}
void
@@ -386,6 +380,21 @@ angfsm_build_reset (angfsm_build_t *fsm)
fsm->run.active_states[i++] = &curs->state;
curs = curs->next;
}
+
+ /* Reset timeouts. */
+ for (i = 0; i < fsm->max_active_states; i++)
+ fsm->run.timeout_counters[i] = -1;
+ for (i = 0; i < fsm->max_active_states; i++)
+ {
+ angfsm_build_timeout_chain_t *toc = fsm->timeouts;
+ while (toc != NULL)
+ {
+ if (fsm->run.active_states[i]->code
+ == toc->timeout.trans->state->code)
+ fsm->run.timeout_counters[i] = toc->timeout.timeout;
+ toc = toc->next;
+ }
+ }
}
void
@@ -476,16 +485,21 @@ angfsm_build_init (angfsm_build_t *fsm, char *name)
fsm->trans = NULL;
fsm->name = name;
fsm->max_active_states = 0;
- fsm->event_nb = 0;
+ fsm->max_events_per_states = 0;
+ fsm->max_branches_per_trans = 1;
fsm->state_nb = 0;
+ fsm->event_nb = 0;
fsm->starters = NULL;
fsm->timeouts = NULL;
+ fsm->u_branch_nb = 0;
+ fsm->u_branch_name = NULL;
fsm->run.trans_table = NULL;
fsm->run.active_states = NULL;
fsm->run.events_before_active_state = NULL;
fsm->run.func_pool = NULL;
fsm->run.timeout_counters = NULL;
+ fsm->run.trans_callback = NULL;
/* Set default user's options. */
fsm->options.embedded_strings = 0;
@@ -502,6 +516,84 @@ angfsm_build_init (angfsm_build_t *fsm, char *name)
angfsm_build_all_fsm = niou;
}
+/* Compute last details about fsm. */
+void
+angfsm_build_init_finalize (angfsm_build_t *fsm)
+{
+ uint i, j, k;
+ uint *cpt;
+ char **t;
+ angfsm_build_trans_chain_t *tc;
+ angfsm_build_branch_chain_t *bc;
+ assert (fsm);
+
+ /* Compute maximal number of events per states. */
+ cpt = (uint *) calloc (fsm->state_nb, sizeof (uint));
+ tc = fsm->trans;
+ while (tc != NULL)
+ {
+ cpt[tc->trans.state->code]++;
+ tc = tc->next;
+ }
+ for (i = 0; i < fsm->state_nb; i++)
+ if (cpt[i] > fsm->max_events_per_states)
+ fsm->max_events_per_states = cpt[i];
+ free (cpt);
+
+ /* Populate every unique branch names. */
+ /* 1. count the number of branch with a name. */
+ j = 0;
+ tc = fsm->trans;
+ while (tc != NULL)
+ {
+ bc = tc->trans.output_branches;
+ while (bc != NULL)
+ {
+ if (bc->name != NULL)
+ j++;
+ bc = bc->next;
+ }
+ tc = tc->next;
+ }
+ /* 2. Create temporary array and fill it. */
+ if (j > 0)
+ {
+ t = (char **) calloc (j, sizeof (char *));
+ k = 0;
+ tc = fsm->trans;
+ /* In all transitions. */
+ while (tc != NULL)
+ {
+ bc = tc->trans.output_branches;
+ /* In all branches. */
+ while (bc != NULL)
+ {
+ if (bc->name != NULL)
+ {
+ /* Check if this name already exists. */
+ int exists = 0;
+ for (i = 0; i < j; i++)
+ if (t[i] && strcmp (bc->name, t[i]) == 0)
+ exists = 1;
+ /* Add to array. */
+ if (!exists)
+ {
+ t[k] = bc->name;
+ k++;
+ }
+ }
+ bc = bc->next;
+ }
+ tc = tc->next;
+ }
+ /* 3. Rescale the array and store it. */
+ if (k < j)
+ t = (char **) realloc (t, k * sizeof (char *));
+ fsm->u_branch_nb = k;
+ fsm->u_branch_name = t;
+ }
+}
+
/* Prepare the fsm to run (at very end). */
void
angfsm_build_run_init (angfsm_build_t *fsm)
@@ -563,8 +655,9 @@ angfsm_build_run_init (angfsm_build_t *fsm)
malloc (fsm->max_active_states * sizeof (int));
for (i = 0; i < fsm->max_active_states; i++)
fsm->run.timeout_counters[i] = -1;
- angfsm_build_timeout_chain_t *toc = fsm->timeouts;
for (i = 0; i < fsm->max_active_states; i++)
+ {
+ angfsm_build_timeout_chain_t *toc = fsm->timeouts;
while (toc != NULL)
{
if (fsm->run.active_states[i]->code
@@ -572,6 +665,7 @@ angfsm_build_run_init (angfsm_build_t *fsm)
fsm->run.timeout_counters[i] = toc->timeout.timeout;
toc = toc->next;
}
+ }
}
void
@@ -671,6 +765,23 @@ angfsm_build_get_state_by_code (angfsm_build_t *fsm, uint state)
return NULL;
}
+angfsm_build_trans_t*
+angfsm_build_get_trans (angfsm_build_t *fsm, uint state, uint event)
+{
+ assert (fsm);
+ assert (state < fsm->state_nb);
+ assert (event < fsm->event_nb);
+
+ angfsm_build_trans_chain_t *tc = fsm->trans;
+ while (tc != NULL)
+ {
+ if (tc->trans.event->code == event && tc->trans.state->code == state)
+ return &(tc->trans);
+ tc = tc->next;
+ }
+ return NULL;
+}
+
uint16_t
angfsm_build_get_event_code (angfsm_build_t *fsm, char *event)
{
@@ -680,6 +791,35 @@ angfsm_build_get_event_code (angfsm_build_t *fsm, char *event)
return e->code;
}
+angfsm_build_branch_chain_t*
+angfsm_build_get_event_branch (angfsm_build_t *fsm,
+ angfsm_build_trans_t *trans,
+ uint branch)
+{
+ assert (fsm);
+ assert (trans);
+ angfsm_build_branch_chain_t *b = trans->output_branches;
+ while (b != NULL)
+ {
+ if (angfsm_build_get_branch (fsm, b->name) == branch)
+ break;
+ b = b->next;
+ }
+ return b;
+}
+
+uint
+angfsm_build_get_branch (angfsm_build_t *fsm, char *branch)
+{
+ assert (fsm);
+ uint i;
+ if (branch && strlen (branch) > 0)
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ if (strcmp (branch, fsm->u_branch_name[i]) == 0)
+ return i;
+ return fsm->u_branch_nb;
+}
+
void
angfsm_build_trans (angfsm_build_t *fsm,
char *state,
@@ -700,6 +840,11 @@ angfsm_build_trans (angfsm_build_t *fsm,
assert (t.event);
angfsm_build_arg_parse (output_branches, &args, &nb);
+
+ /* Are we the winner of the maximal branches per transitions ? */
+ if ((uint) ((nb / 2)) > fsm->max_branches_per_trans)
+ fsm->max_branches_per_trans = nb / 2;
+
/* Only one output state. */
if (nb == 1)
{
@@ -717,6 +862,9 @@ angfsm_build_trans (angfsm_build_t *fsm,
malloc (sizeof (angfsm_build_branch_chain_t));
b->name = strdup (args[i]);
b->state = angfsm_build_get_state (fsm, args[i + 1]);
+ if (!b->state)
+ fprintf (stderr, "Error: the state \"%s\" has not been declared in fsm %s.\n",
+ args[i + 1], fsm->name);
assert (b->state);
b->next = t.output_branches;
t.output_branches = b;
@@ -806,8 +954,12 @@ angfsm_build_handle (angfsm_build_t *fsm, angfsm_build_event_t *e)
{
angfsm_build_state_t *s = NULL;
angfsm_build_timeout_chain_t *toc = NULL;
+ angfsm_build_state_t *out;
+ angfsm_build_branch_chain_t* bc;
assert (e);
uint i;
+ uint b = 0;
+ int mono;
int handled = 0;
for (i = 0; i < fsm->max_active_states; i++)
{
@@ -815,7 +967,52 @@ angfsm_build_handle (angfsm_build_t *fsm, angfsm_build_event_t *e)
if (s && fsm->run.trans_table[e->code][s->code])
{
fsm->run.events_before_active_state[i] = e;
- fsm->run.active_states[i] = fsm->run.trans_table[e->code][s->code]();
+
+ /* Get transition. */
+ angfsm_build_trans_t *t = angfsm_build_get_trans (fsm, s->code, e->code);
+ assert (t);
+
+ /* Is it a mono or multi branch function ? */
+ assert (t->output_branches);
+ if (t->output_branches->next == NULL)
+ mono = 1;
+ else
+ mono = 0;
+
+ /* Get transition function. */
+ angfsm_build_run_strans_func_t f = fsm->run.trans_table[e->code][s->code];
+ angfsm_build_run_strans_func_branches_t fb = (angfsm_build_run_strans_func_branches_t) f;
+
+ /* Run transition. */
+ if (mono)
+ f ();
+ else
+ b = fb();
+
+ /* Get next branch. */
+ bc = NULL;
+ if (mono)
+ bc = t->output_branches;
+ else
+ bc = angfsm_build_get_event_branch (fsm, t, b);
+
+ if (bc == NULL)
+ fprintf (stderr, "FSM: %s STATE: %s EVENT: %s - Cannot handle given branch \"%s\" (%s)\n", fsm->name, s->var_name, e->var_name, (b < fsm->u_branch_nb ? fsm->u_branch_name[b] : ""), (b < fsm->u_branch_nb ? "wrong branch ?" : "bad branch name ?"));
+ assert (bc);
+ out = bc->state;
+ assert (out);
+
+ /* Transition print. */
+ if (fsm->options.print_trans)
+ angfsm_build_print_trans (fsm, t, bc);
+
+ /* Transition callback. */
+ if (fsm->run.trans_callback)
+ fsm->run.trans_callback (s->code, e->code, out->code, (mono ? -1 : (int) b));
+
+ /* Update active states. */
+ fsm->run.active_states[i] = out;
+
/* Check the new state has a timeout or not. */
toc = fsm->timeouts;
fsm->run.timeout_counters[i] = -1;
@@ -905,57 +1102,6 @@ angfsm_build_handle_timeout (angfsm_build_t *fsm)
return out;
}
-angfsm_build_state_t*
-angfsm_build_get_next_state (angfsm_build_t *fsm,
- char *state,
- char *event,
- char *branch)
-{
- angfsm_build_state_t *s;
- angfsm_build_event_t *e;
- angfsm_build_trans_chain_t *t_curs;
- angfsm_build_branch_chain_t *b_curs;
-
- /* Convert input data. */
- s = angfsm_build_get_state (fsm, state);
- e = angfsm_build_get_event (fsm, event);
- assert (s && e);
-
- /* Get transition. */
- t_curs = fsm->trans;
- while (t_curs != NULL)
- {
- if (s == t_curs->trans.state && e == t_curs->trans.event)
- break;
- t_curs = t_curs->next;
- }
- assert (t_curs);
- assert (t_curs->trans.output_branches);
-
- /* If we have only one branch. */
- if (strlen (branch) == 0)
- {
- /* Branch has to be given is there are multiple branches. */
- assert (t_curs->trans.output_branches->next == NULL);
- if (fsm->options.print_trans)
- angfsm_build_print (fsm, &t_curs->trans, t_curs->trans.output_branches);
- return t_curs->trans.output_branches->state;
- }
-
- /* Find correct branch. */
- b_curs = t_curs->trans.output_branches;
- while (b_curs != NULL)
- {
- if (strcmp (b_curs->name, branch) == 0)
- break;
- b_curs = b_curs->next;
- }
- assert (b_curs);
- if (fsm->options.print_trans)
- angfsm_build_print (fsm, &t_curs->trans, b_curs);
- return b_curs->state;
-}
-
int
angfsm_build_options (int argc, char **argv)
{
@@ -1098,11 +1244,8 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
angfsm_build_state_chain_t *sc;
angfsm_build_event_chain_t *ec;
angfsm_build_trans_chain_t *tc;
- angfsm_build_branch_chain_t *bc;
- angfsm_build_state_t *s;
- angfsm_build_event_t *e;
angfsm_build_chain_t *all_fsm;
- uint i, j;
+ uint i;
uint embedded_strings = fsm->options.embedded_strings;
/* Open file. */
@@ -1135,6 +1278,16 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fsm->name,
fsm->max_active_states);
+ /* Gen max number of events per states. */
+ fprintf (f, "#define angfsm_%s_max_events_per_states %u\n",
+ fsm->name,
+ fsm->max_events_per_states);
+
+ /* Gen max number of branches per transitions. */
+ fprintf (f, "#define angfsm_%s_max_branches_per_trans %u\n",
+ fsm->name,
+ fsm->max_branches_per_trans);
+
/* Gen state enum. */
fprintf (f, "typedef enum\n{\n");
sc = fsm->states;
@@ -1143,9 +1296,12 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "\tangfsm_STATE_%s_%s = %u,\n", fsm->name, sc->state.var_name, sc->state.code);
sc = sc->next;
}
- fprintf (f, "\tangfsm_STATE_%s_NB_ = %u\n", fsm->name, fsm->state_nb);
+ fprintf (f, "\tangfsm_STATE_%s_NB = %u\n", fsm->name, fsm->state_nb);
fprintf (f, "} angfsm_%s_state_t;\n\n", fsm->name);
+ /* Gen transition callback reference. */
+ fprintf (f, "extern void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name);
+
/* Gen event enum. */
fprintf (f, "typedef enum\n{\n");
ec = fsm->events;
@@ -1154,133 +1310,106 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "\tangfsm_EVENT_%s_%s = %u,\n", fsm->name, ec->event.var_name, ec->event.code);
ec = ec->next;
}
- fprintf (f, "\tangfsm_EVENT_%s_NB_ = %u\n", fsm->name, fsm->event_nb);
+ fprintf (f, "\tangfsm_EVENT_%s_NB = %u\n", fsm->name, fsm->event_nb);
fprintf (f, "} angfsm_%s_event_t;\n\n", fsm->name);
- /* Gen state strings. */
- if (embedded_strings)
+ /* Gen branches unique name enum. */
+ fprintf (f, "typedef enum\n{\n");
+ if (fsm->u_branch_nb > 0)
{
- sc = fsm->states;
- while (sc != NULL)
- {
- fprintf (f, "extern char angfsm_%s_state_str_%s[%u];\n",
- fsm->name,
- sc->state.var_name,
- strlen (sc->state.var_name) + 1);
- sc = sc->next;
- }
- fprintf (f, "extern char *angfsm_%s_state_str[%u];\n\n",
- fsm->name,
- fsm->state_nb);
-
- /* Gen event strings. */
- ec = fsm->events;
- while (ec != NULL)
- {
- fprintf (f, "extern char angfsm_%s_event_str_%s[%u];\n",
- fsm->name,
- ec->event.var_name,
- strlen (ec->event.var_name) + 1);
- ec = ec->next;
- }
- fprintf (f, "extern char *angfsm_%s_event_str[%u];\n\n",
- fsm->name,
- fsm->event_nb);
-
- /* Create a RAM string able to store event or state string. */
- j = 0;
- for (i = 0; i < fsm->event_nb; i++)
- {
- e = angfsm_build_get_event_by_code (fsm, i);
- if (strlen (e->var_name) > j)
- j = strlen (e->var_name);
- }
- for (i = 0; i < fsm->state_nb; i++)
- {
- s = angfsm_build_get_state_by_code (fsm, i);
- if (strlen (s->var_name) > j)
- j = strlen (s->var_name);
- }
- fprintf (f, "extern char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1);
-
- /* Convert an event enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \
- (angfsm_%s_event_t e);\n", fsm->name, fsm->name);
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ fprintf (f, "\tangfsm_BRANCH_%s_%s = %u,\n",
+ fsm->name,
+ fsm->u_branch_name[i],
+ i);
+ }
+ fprintf (f, "\tangfsm_BRANCH_%s_NB = %u\n", fsm->name, fsm->u_branch_nb);
+ fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name);
- /* Convert a event string in enum. */
- fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \
- (char *str);\n", fsm->name, fsm->name);
+ /* Gen strings. */
+ if (embedded_strings)
+ {
+ fprintf (f, "extern char *angfsm_%s_state_str[];\n", fsm->name);
+ fprintf (f, "extern char *angfsm_%s_event_str[];\n", fsm->name);
+ fprintf (f, "extern char *angfsm_%s_branch_str[];\n", fsm->name);
- /* Convert an state enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \
- (angfsm_%s_state_t s);\n", fsm->name, fsm->name);
+ /* Convert an event in string. */
+ fprintf (f, "char *\nangfsm_%s_get_event_str (angfsm_%s_event_t e);\n", fsm->name, fsm->name);
+ /* Convert a state in string. */
+ fprintf (f, "char *\nangfsm_%s_get_state_str (angfsm_%s_state_t s);\n", fsm->name, fsm->name);
+ /* Convert a branch in string. */
+ fprintf (f, "char *\nangfsm_%s_get_branch_str (angfsm_%s_branch_t s);\n", fsm->name, fsm->name);
- /* Convert a state string in enum. */
- fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \
- (char *str);\n", fsm->name, fsm->name);
+ fprintf (f, "\n");
}
-
- /* Gen transitions branches enum. */
- fprintf (f, "typedef enum\n{\n");
- tc = fsm->trans;
- while (tc != NULL)
+ else
{
- bc = tc->trans.output_branches;
- while (bc != NULL)
- {
- if (bc->name != NULL)
- fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_%s = %u,\n",
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name,
- bc->name,
- bc->state->code);
- else
- fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_ = %u,\n",
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name,
- bc->state->code);
- bc = bc->next;
- }
- tc = tc->next;
+ /* Disable string macros. */
+ fprintf (f, "#undef ANGFSM_STATE_STR\n#define ANGFSM_STATE_STR(s) ((char *)0)\n");
+ fprintf (f, "#undef ANGFSM_EVENT_STR\n#define ANGFSM_EVENT_STR(e) ((char *)0)\n");
+ fprintf (f, "#undef ANGFSM_BRANCH_STR\n#define ANGFSM_BRANCH_STR(b) ((char *)0)\n");
}
- fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name);
/* Gen function headers. */
tc = fsm->trans;
while (tc != NULL)
{
- fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s (void);\n",
- fsm->name,
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name);
+ assert (tc->trans.output_branches);
+ /* Mono branch */
+ if (tc->trans.output_branches->next==NULL)
+ fprintf (f, "void angfsm_%s_trans_func_%s_%s ();\n",
+ fsm->name,
+ tc->trans.state->var_name,
+ tc->trans.event->var_name);
+ else
+ fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s ();\n",
+ fsm->name,
+ fsm->name,
+ tc->trans.state->var_name,
+ tc->trans.event->var_name);
tc = tc->next;
}
fprintf (f, "\n");
- /* Gen function table. */
- fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_t)(void);\n", fsm->name,
+ /* Declare function type. */
+ fprintf (f, "typedef void (*angfsm_%s_func_t)();\n", fsm->name);
+ fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_branches_t)();\n\n",
+ fsm->name, fsm->name);
+
+ /* Gen branch structure. */
+ fprintf (f, "typedef struct\n{\n");
+ fprintf (f, "\tangfsm_%s_branch_t branch;\n", fsm->name);
+ fprintf (f, "\tangfsm_%s_state_t state;\n", fsm->name);
+ fprintf (f, "} angfsm_%s_next_t;\n\n", fsm->name);
+
+ /* Gen transition structure. */
+ fprintf (f, "typedef struct\n{\n");
+ fprintf (f, "\tangfsm_%s_event_t event;\n", fsm->name);
+ fprintf (f, "\tangfsm_%s_func_t func;\n", fsm->name);
+ fprintf (f, "\tangfsm_%s_next_t branches[angfsm_%s_max_branches_per_trans];\n",
+ fsm->name,
fsm->name);
- fprintf (f, "extern const angfsm_%s_func_t angfsm_%s_trans_table[%u][%u];\n",
+ fprintf (f, "} angfsm_%s_trans_t;\n\n", fsm->name);
+
+ /* Gen transition table. */
+ fprintf (f, "extern const angfsm_%s_trans_t angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states];\n\n",
+ fsm->name,
fsm->name,
fsm->name,
- fsm->event_nb,
- fsm->state_nb);
+ fsm->name);
+
/* Gen read function for trans table. */
- fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, "
- "angfsm_%s_state_t state);\n\n",
+ fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans (angfsm_%s_event_t event, angfsm_%s_state_t state);\n\n",
fsm->name,
fsm->name,
fsm->name,
fsm->name);
/* Gen active states array. */
- fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n",
+ fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n",
fsm->name,
fsm->name,
- fsm->max_active_states);
+ fsm->name);
/* Gen initialization function. */
sc = fsm->starters;
@@ -1305,20 +1434,20 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fsm->name);
/* Gen timeout values. */
- fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_];\n",
+ fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB];\n",
fsm->name,
fsm->name);
/* Gen timeout corresponding events. */
- fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_];\n",
+ fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB];\n",
fsm->name,
fsm->name,
fsm->name);
/* Gen timeout counters array. */
- fprintf (f, "extern int32_t angfsm_%s_timeout_counters[%u];\n\n",
+ fprintf (f, "extern int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n\n",
fsm->name,
- fsm->max_active_states);
+ fsm->name);
}
/* Conclusion. */
@@ -1332,14 +1461,15 @@ angfsm_build_gen_no_opti_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
void
angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
{
+ assert (fsm);
assert (arch < ANGFSM_BUILD_ARCH_NB);
angfsm_build_state_chain_t *sc;
angfsm_build_event_chain_t *ec;
angfsm_build_trans_chain_t *tc;
angfsm_build_timeout_chain_t *toc;
+ angfsm_build_branch_chain_t *bc;
angfsm_build_state_t *s;
- angfsm_build_event_t *e;
- uint i, j, found;
+ uint i, j, k, count;
uint embedded_strings = fsm->options.embedded_strings;
/* Open file. */
@@ -1356,165 +1486,191 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
angfsm_build_arch_name[arch],
fsm->name);
- /* Gen state strings. */
+ /* Gen strings if configured. */
if (embedded_strings)
{
- sc = fsm->states;
- while (sc != NULL)
- {
- fprintf (f, "char angfsm_%s_state_str_%s[] = \"%s\";\n",
- fsm->name,
- sc->state.var_name,
- sc->state.var_name);
- sc = sc->next;
- }
+ /* Gen state strings. */
fprintf (f, "char *angfsm_%s_state_str[] =\n{\n", fsm->name);
for (i = 0; i < fsm->state_nb; i++)
{
- s = angfsm_build_get_state_by_code (fsm, i);
- fprintf (f, "\tangfsm_%s_state_str_%s", fsm->name, s->var_name);
- if (i == fsm->state_nb - 1)
- fprintf (f, "\n");
- else
- fprintf (f, ",\n");
+ sc = fsm->states;
+ while (sc != NULL)
+ {
+ if (sc->state.code == i)
+ {
+ fprintf (f, "\t\"%s\"", sc->state.var_name);
+ if (i != fsm->state_nb)
+ fprintf (f, ", ");
+ fprintf (f, "\n");
+ }
+ sc = sc->next;
+ }
}
fprintf (f, "};\n\n");
/* Gen event strings. */
- ec = fsm->events;
- while (ec != NULL)
- {
- fprintf (f, "char angfsm_%s_event_str_%s[] = \"%s\";\n",
- fsm->name,
- ec->event.var_name,
- ec->event.var_name);
- ec = ec->next;
- }
fprintf (f, "char *angfsm_%s_event_str[] =\n{\n", fsm->name);
for (i = 0; i < fsm->event_nb; i++)
{
- e = angfsm_build_get_event_by_code (fsm, i);
- fprintf (f, "\tangfsm_%s_event_str_%s", fsm->name, e->var_name);
- if (i == fsm->event_nb - 1)
- fprintf (f, "\n");
- else
- fprintf (f, ",\n");
+ ec = fsm->events;
+ while (ec != NULL)
+ {
+ if (ec->event.code == i)
+ {
+ fprintf (f, "\t\"%s\"", ec->event.var_name);
+ if (i != fsm->event_nb)
+ fprintf (f, ", ");
+ fprintf (f, "\n");
+ }
+ ec = ec->next;
+ }
}
fprintf (f, "};\n\n");
- /* Create a RAM string able to store event or state string. */
- j = 0;
- for (i = 0; i < fsm->event_nb; i++)
+ /* Gen branch strings. */
+ fprintf (f, "char *angfsm_%s_branch_str[] =\n{\n", fsm->name);
+ for (i = 0; i < fsm->u_branch_nb; i++)
{
- e = angfsm_build_get_event_by_code (fsm, i);
- if (strlen (e->var_name) > j)
- j = strlen (e->var_name);
- }
- for (i = 0; i < fsm->state_nb; i++)
- {
- s = angfsm_build_get_state_by_code (fsm, i);
- if (strlen (s->var_name) > j)
- j = strlen (s->var_name);
+ fprintf (f, "\t\"%s\"", fsm->u_branch_name[i]);
+ if (i != fsm->u_branch_nb - 1)
+ fprintf (f, ", ");
+ fprintf (f, "\n");
}
- fprintf (f, "char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1);
+ fprintf (f, "};\n\n");
+ /* Generate string read functions. */
/* Convert an event enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \
- (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name);
- fprintf (f, "\treturn strcpy (angfsm_%s_str_buff, \
- (char *) (&(angfsm_%s_event_str[e])));\n", fsm->name, fsm->name);
- fprintf (f, "}\n\n");
-
- /* Convert a event string in enum. */
- fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \
- (char *str)\n{\n", fsm->name, fsm->name);
- fprintf (f, "\tuint16_t i;\n");
- fprintf (f, "\tfor (i = 0; i < angfsm_EVENT_%s_NB_; i++)\n", fsm->name);
- fprintf (f, "\t\tif (strcpy (str, \
- (char *) (&(angfsm_%s_event_str[i]))) == 0)\n", fsm->name);
- fprintf (f, "\t\t\treturn i;\n");
- fprintf (f, "\treturn angfsm_EVENT_%s_NB_;\n", fsm->name);
+ fprintf (f, "inline char *\nangfsm_%s_get_event_str (angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name);
+ fprintf (f, "\treturn angfsm_%s_event_str[e];\n", fsm->name);
fprintf (f, "}\n\n");
-
- /* Convert an state enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \
- (angfsm_%s_state_t s)\n{\n", fsm->name, fsm->name);
- fprintf (f, "\treturn strcpy (angfsm_%s_str_buff, \
- (char *) (&(angfsm_%s_state_str[s])));\n", fsm->name, fsm->name);
+ /* Convert a state enum in string. */
+ fprintf (f, "inline char *\nangfsm_%s_get_state_str (angfsm_%s_state_t s)\n{\n", fsm->name, fsm->name);
+ fprintf (f, "\treturn angfsm_%s_state_str[s];\n", fsm->name);
fprintf (f, "}\n\n");
-
- /* Convert a state string in enum. */
- fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \
- (char *str)\n{\n", fsm->name, fsm->name);
- fprintf (f, "\tuint16_t i;\n");
- fprintf (f, "\tfor (i = 0; i < angfsm_STATE_%s_NB_; i++)\n", fsm->name);
- fprintf (f, "\t\tif (strcpy (str, \
- (char *) (&(angfsm_%s_state_str[i]))) == 0)\n", fsm->name);
- fprintf (f, "\t\t\treturn i;\n");
- fprintf (f, "\treturn angfsm_STATE_%s_NB_;\n", fsm->name);
+ /* Convert a branch enum in string. */
+ fprintf (f, "inline char *\nangfsm_%s_get_branch_str (angfsm_%s_branch_t b)\n{\n", fsm->name, fsm->name);
+ fprintf (f, "\treturn angfsm_%s_branch_str[b];\n", fsm->name);
fprintf (f, "}\n\n");
}
- /* Gen function table. */
- fprintf (f, "const angfsm_%s_func_t angfsm_%s_trans_table[%u][%u] = \n{\n",
+ /* Gen transition table. */
+ fprintf (f, "const angfsm_%s_trans_t angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states] = \n{\n",
fsm->name,
fsm->name,
- fsm->event_nb,
- fsm->state_nb);
- /* for each events and state, see if it exists an associated transition. */
- for (i = 0; i < fsm->event_nb; i++)
+ fsm->name,
+ fsm->name);
+ for (i = 0; i < fsm->state_nb; i++)
{
- e = angfsm_build_get_event_by_code (fsm, i);
- fprintf (f, "\t{");
- for (j = 0; j < fsm->state_nb; j++)
+ count = 0;
+ fprintf (f, "\t{\n");
+ tc = fsm->trans;
+ while (tc != NULL)
{
- s = angfsm_build_get_state_by_code (fsm, j);
- tc = fsm->trans;
- found = 0;
- while (tc != NULL)
- {
- if (tc->trans.state == s && tc->trans.event == e)
- {
- found = 1;
- fprintf (f, "&angfsm_%s_trans_func_%s_%s",
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name);
- tc = tc->next;
- break;
- }
- tc = tc->next;
- }
- if (!found)
- fprintf (f, "(angfsm_%s_func_t) 0", fsm->name);
- if (j == fsm->state_nb - 1)
- fprintf (f, "}");
- else
- fprintf (f, ", ");
+ if (tc->trans.state->code == i)
+ {
+ fprintf (f, "\t\t{\n");
+ fprintf (f, "\t\t\tangfsm_EVENT_%s_%s,\n",
+ fsm->name,
+ tc->trans.event->var_name);
+ fprintf (f, "\t\t\t(angfsm_%s_func_t) &angfsm_%s_trans_func_%s_%s,\n",
+ fsm->name,
+ fsm->name,
+ tc->trans.state->var_name,
+ tc->trans.event->var_name);
+ /* Gen branche array */
+ fprintf (f, "\t\t\t{\n");
+ j = 0;
+ bc = tc->trans.output_branches;
+ while (bc != NULL)
+ {
+ fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_%s, angfsm_STATE_%s_%s}",
+ fsm->name,
+ (bc->name ? bc->name : "NB"),
+ fsm->name,
+ bc->state->var_name);
+ if (j != fsm->max_branches_per_trans - 1)
+ fprintf (f, ", ");
+ fprintf (f, "\n");
+ j++;
+ bc = bc->next;
+ }
+ /* Fill blank branches. */
+ for (k = j; k < fsm->max_branches_per_trans; k++)
+ {
+ fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}",
+ fsm->name,
+ fsm->name);
+ if (k != fsm->max_branches_per_trans - 1)
+ fprintf (f, ",");
+ fprintf (f, "\n");
+ }
+
+ fprintf (f, "\t\t\t}\n");
+ if (tc->next != NULL || count != fsm->max_events_per_states)
+ fprintf (f, "\t\t},\n");
+ else
+ fprintf (f, "\t\t}\n");
+ count++;
+ }
+ tc = tc->next;
}
- if (i != fsm->event_nb - 1)
- fprintf (f, ",");
- fprintf (f, "\n");
+ /* Fill blank transitions. */
+ for (k = count; k < fsm->max_events_per_states; k++)
+ {
+ fprintf (f, "\t\t{\n");
+ fprintf (f, "\t\t\tangfsm_EVENT_%s_NB,\n",fsm->name);
+ fprintf (f, "\t\t\t(angfsm_%s_func_t) 0,\n", fsm->name);
+ fprintf (f, "\t\t\t{\n");
+ for (j = 0; j < fsm->max_branches_per_trans; j++)
+ {
+ fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}",
+ fsm->name,
+ fsm->name);
+ if (j != fsm->max_branches_per_trans - 1)
+ fprintf (f, ",");
+ fprintf (f, "\n");
+ }
+ fprintf (f, "\t\t\t}\n");
+ if (k != fsm->max_events_per_states - 1)
+ fprintf (f, "\t\t},\n");
+ else
+ fprintf (f, "\t\t}\n");
+ }
+
+ if (i == fsm->state_nb - 1)
+ fprintf (f, "\t}\n");
+ else
+ fprintf (f, "\t},\n");
}
fprintf (f, "};\n\n");
- /* Gen read function for trans table. */
- fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, "
- "angfsm_%s_state_t state)\n{\n",
- fsm->name,
- fsm->name,
+ /* Transition callback. */
+ fprintf (f, "void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name);
+
+ /* Gen active states array. */
+ fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n",
fsm->name,
- fsm->name);
- fprintf (f, "\treturn (angfsm_%s_func_t) angfsm_%s_trans_table[event][state];\n",
fsm->name,
fsm->name);
- fprintf (f, "}\n\n");
- /* Gen active states array. */
- fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n",
+ /* Gen read transition from event and state. */
+ fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans "
+ "(angfsm_%s_event_t event, angfsm_%s_state_t state)\n{\n",
fsm->name,
fsm->name,
- fsm->max_active_states);
+ fsm->name,
+ fsm->name);
+ fprintf (f, "\tint i;\n");
+ fprintf (f, "\tangfsm_%s_trans_t* t;\n", fsm->name);
+ fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_events_per_states; i++)\n\t{\n",
+ fsm->name);
+ fprintf (f, "\t\tt = (angfsm_%s_trans_t *) (&angfsm_%s_trans_table[state][i]);\n",
+ fsm->name,
+ fsm->name);
+ fprintf (f, "\t\tif (t->func == (angfsm_%s_func_t) 0)\n\t\t\tbreak;\n", fsm->name);
+ fprintf (f, "\t\tif (t->event == event)\n");
+ fprintf (f, "\t\t\treturn t;\n");
+ fprintf (f, "\t}\n\treturn (angfsm_%s_trans_t*) 0;\n}\n\n", fsm->name);
/* Gen initialization function. */
sc = fsm->starters;
@@ -1522,11 +1678,11 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "void\nangfsm_%s_init ()\n{\n", fsm->name);
while (sc != NULL)
{
- fprintf (f, "\tangfsm_%s_active_states[%u] = (angfsm_%s_state_t) %u;\n",
+ fprintf (f, "\tangfsm_%s_active_states[%u] = angfsm_STATE_%s_%s;\n",
fsm->name,
i,
fsm->name,
- sc->state.code);
+ sc->state.var_name);
if (fsm->timeouts != NULL)
{
toc = fsm->timeouts;
@@ -1545,23 +1701,43 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
i++;
sc = sc->next;
}
+ /* Set transition callback to NULL. */
+ fprintf (f, "\tangfsm_%s_trans_callback = (typeof (angfsm_%s_trans_callback)) 0;\n", fsm->name, fsm->name);
fprintf (f, "}\n\n");
/* Gen handle function. */
fprintf (f, "int\nangfsm_%s_handle (angfsm_%s_event_t e)\n{\n",
fsm->name,
fsm->name);
- fprintf (f, "\tuint16_t i;\n");
+ fprintf (f, "\tuint16_t i, j;\n");
fprintf (f, "\tint handled = 0;\n");
+ fprintf (f, "\tangfsm_%s_branch_t b;\n", fsm->name);
fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_active_states; i++)\n\t{\n",
fsm->name);
- fprintf (f, "\t\tangfsm_%s_func_t trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n",
+ fprintf (f, "\t\tangfsm_%s_trans_t *trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n",
fsm->name,
fsm->name,
fsm->name);
fprintf (f, "\t\tif (trans)\n");
fprintf (f, "\t\t{\n");
- fprintf (f, "\t\t\tangfsm_%s_active_states[i] = (angfsm_%s_state_t) trans ();\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\tangfsm_%s_state_t s = angfsm_STATE_%s_NB;\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\tif (trans->branches[0].branch == angfsm_BRANCH_%s_NB)\n\t\t\t{\n", fsm->name);
+ fprintf (f, "\t\t\t\ttrans->func ();\n");
+ fprintf (f, "\t\t\t\ts = trans->branches[0].state;\n");
+ fprintf (f, "\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name);
+ fprintf (f, "\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, -1);\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\t}\n\t\t\telse\n\t\t\t{\n");
+ fprintf (f, "\t\t\t\tb = ((angfsm_%s_func_branches_t) trans->func) ();\n", fsm->name);
+ fprintf (f, "\t\t\t\tfor (j = 0; j < angfsm_%s_max_branches_per_trans; j++)\n", fsm->name);
+ fprintf (f, "\t\t\t\t\tif (trans->branches[j].branch == b)\n");
+ fprintf (f, "\t\t\t\t\t\ts = trans->branches[j].state;\n");
+ fprintf (f, "\t\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name);
+ fprintf (f, "\t\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, b);\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\t}\n");
+ fprintf (f, "\t\t\tif (s != angfsm_STATE_%s_NB)\n", fsm->name);
+ fprintf (f, "\t\t\t\tangfsm_%s_active_states[i] = s;\n", fsm->name);
+ fprintf (f, "\t\t\telse\n");
+ fprintf (f, "\t\t\t\t{;} //XXX show some error ?\n");
fprintf (f, "\t\t\thandled = 1;\n");
if (fsm->timeouts != NULL)
{
@@ -1593,12 +1769,12 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
if (fsm->timeouts != NULL)
{
/* Gen timeout counters array. */
- fprintf (f, "int32_t angfsm_%s_timeout_counters[%u];\n",
+ fprintf (f, "int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n",
fsm->name,
- fsm->max_active_states);
+ fsm->name);
/* Gen timeout values array. */
- fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_] =\n{\n",
+ fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB] =\n{\n",
fsm->name,
fsm->name);
int value;
@@ -1625,7 +1801,7 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "};\n\n");
/* Gen timeout corresponding events array. */
- fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_] =\n{\n",
+ fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB] =\n{\n",
fsm->name,
fsm->name,
fsm->name);
@@ -1645,7 +1821,7 @@ angfsm_build_gen_no_opti_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
toc = toc->next;
}
if (value == -1)
- fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB_", fsm->name, fsm->name);
+ fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB", fsm->name, fsm->name);
else
fprintf (f, "\t(angfsm_%s_event_t) %u", fsm->name, value);
@@ -1692,10 +1868,10 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
angfsm_build_state_chain_t *sc;
angfsm_build_event_chain_t *ec;
angfsm_build_trans_chain_t *tc;
- angfsm_build_branch_chain_t *bc;
+ angfsm_build_chain_t *all_fsm;
angfsm_build_state_t *s;
angfsm_build_event_t *e;
- angfsm_build_chain_t *all_fsm;
+
uint i, j;
uint embedded_strings = fsm->options.embedded_strings;
@@ -1729,6 +1905,16 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fsm->name,
fsm->max_active_states);
+ /* Gen max number of events per states. */
+ fprintf (f, "#define angfsm_%s_max_events_per_states %u\n",
+ fsm->name,
+ fsm->max_events_per_states);
+
+ /* Gen max number of branches per transitions. */
+ fprintf (f, "#define angfsm_%s_max_branches_per_trans %u\n",
+ fsm->name,
+ fsm->max_branches_per_trans);
+
/* Gen state enum. */
fprintf (f, "typedef enum\n{\n");
sc = fsm->states;
@@ -1737,9 +1923,12 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "\tangfsm_STATE_%s_%s = %u,\n", fsm->name, sc->state.var_name, sc->state.code);
sc = sc->next;
}
- fprintf (f, "\tangfsm_STATE_%s_NB_ = %u\n", fsm->name, fsm->state_nb);
+ fprintf (f, "\tangfsm_STATE_%s_NB = %u\n", fsm->name, fsm->state_nb);
fprintf (f, "} angfsm_%s_state_t;\n\n", fsm->name);
+ /* Gen transition callback reference. */
+ fprintf (f, "extern void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name);
+
/* Gen event enum. */
fprintf (f, "typedef enum\n{\n");
ec = fsm->events;
@@ -1748,12 +1937,26 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "\tangfsm_EVENT_%s_%s = %u,\n", fsm->name, ec->event.var_name, ec->event.code);
ec = ec->next;
}
- fprintf (f, "\tangfsm_EVENT_%s_NB_ = %u\n", fsm->name, fsm->event_nb);
+ fprintf (f, "\tangfsm_EVENT_%s_NB = %u\n", fsm->name, fsm->event_nb);
fprintf (f, "} angfsm_%s_event_t;\n\n", fsm->name);
- /* Gen state strings. */
+ /* Gen branches unique name enum. */
+ fprintf (f, "typedef enum\n{\n");
+ if (fsm->u_branch_nb > 0)
+ {
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ fprintf (f, "\tangfsm_BRANCH_%s_%s = %u,\n",
+ fsm->name,
+ fsm->u_branch_name[i],
+ i);
+ }
+ fprintf (f, "\tangfsm_BRANCH_%s_NB = %u\n", fsm->name, fsm->u_branch_nb);
+ fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name);
+
+ /* Gen strings. */
if (embedded_strings)
{
+ /* Gen state strings header. */
sc = fsm->states;
while (sc != NULL)
{
@@ -1767,7 +1970,7 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fsm->name,
fsm->state_nb);
- /* Gen event strings. */
+ /* Gen event strings header. */
ec = fsm->events;
while (ec != NULL)
{
@@ -1781,6 +1984,18 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fsm->name,
fsm->event_nb);
+ /* Gen branch strings header. */
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ {
+ fprintf (f, "extern prog_char angfsm_%s_branch_str_%s[%u] PROGMEM;\n",
+ fsm->name,
+ fsm->u_branch_name[i],
+ strlen (fsm->u_branch_name[i]) + 1);
+ }
+ fprintf (f, "extern const char *angfsm_%s_branch_str[%u] PROGMEM;\n\n",
+ fsm->name,
+ fsm->u_branch_nb);
+
/* Create a RAM string able to store event or state string. */
j = 0;
for (i = 0; i < fsm->event_nb; i++)
@@ -1795,86 +2010,88 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
if (strlen (s->var_name) > j)
j = strlen (s->var_name);
}
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ {
+ if (strlen (fsm->u_branch_name[i]) > j)
+ j = strlen (fsm->u_branch_name[i]);
+ }
fprintf (f, "extern char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1);
- /* Convert an event enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \
- (angfsm_%s_event_t e);\n", fsm->name, fsm->name);
-
- /* Convert a event string in enum. */
- fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \
- (char *str);\n", fsm->name, fsm->name);
-
- /* Convert an state enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \
- (angfsm_%s_state_t s);\n", fsm->name, fsm->name);
-
- /* Convert a state string in enum. */
- fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \
- (char *str);\n", fsm->name, fsm->name);
+ /* Convert an event in string. */
+ fprintf (f, "char *\nangfsm_%s_get_event_str (angfsm_%s_event_t e);\n", fsm->name, fsm->name);
+ /* Convert a state in string. */
+ fprintf (f, "char *\nangfsm_%s_get_state_str (angfsm_%s_state_t s);\n", fsm->name, fsm->name);
+ /* Convert a branch in string. */
+ fprintf (f, "char *\nangfsm_%s_get_branch_str (angfsm_%s_branch_t s);\n", fsm->name, fsm->name);
}
-
- /* Gen transitions branches enum. */
- fprintf (f, "typedef enum\n{\n");
- tc = fsm->trans;
- while (tc != NULL)
+ else
{
- bc = tc->trans.output_branches;
- while (bc != NULL)
- {
- if (bc->name != NULL)
- fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_%s = %u,\n",
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name,
- bc->name,
- bc->state->code);
- else
- fprintf (f, "\tangfsm_BRANCH_%s_%s_%s_ = %u,\n",
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name,
- bc->state->code);
- bc = bc->next;
- }
- tc = tc->next;
+ /* Disable string macros. */
+ fprintf (f, "#undef ANGFSM_STATE_STR\n#define ANGFSM_STATE_STR(s) ((char *)0)\n");
+ fprintf (f, "#undef ANGFSM_EVENT_STR\n#define ANGFSM_EVENT_STR(e) ((char *)0)\n");
+ fprintf (f, "#undef ANGFSM_BRANCH_STR\n#define ANGFSM_BRANCH_STR(b) ((char *)0)\n");
}
- fprintf (f, "} angfsm_%s_branch_t;\n\n", fsm->name);
/* Gen function headers. */
tc = fsm->trans;
while (tc != NULL)
{
- fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s (void);\n",
- fsm->name,
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name);
+ assert (tc->trans.output_branches);
+ /* Mono branch */
+ if (tc->trans.output_branches->next==NULL)
+ fprintf (f, "void angfsm_%s_trans_func_%s_%s ();\n",
+ fsm->name,
+ tc->trans.state->var_name,
+ tc->trans.event->var_name);
+ else
+ fprintf (f, "angfsm_%s_branch_t angfsm_%s_trans_func_%s_%s ();\n",
+ fsm->name,
+ fsm->name,
+ tc->trans.state->var_name,
+ tc->trans.event->var_name);
tc = tc->next;
}
fprintf (f, "\n");
- /* Gen function table. */
- fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_t)(void);\n", fsm->name,
+ /* Declare function type. */
+ fprintf (f, "typedef void (*angfsm_%s_func_t)();\n", fsm->name);
+ fprintf (f, "typedef angfsm_%s_branch_t (*angfsm_%s_func_branches_t)();\n\n",
+ fsm->name, fsm->name);
+
+ /* Gen branch structure. */
+ fprintf (f, "typedef struct\n{\n");
+ fprintf (f, "\tangfsm_%s_branch_t branch;\n", fsm->name);
+ fprintf (f, "\tangfsm_%s_state_t state;\n", fsm->name);
+ fprintf (f, "} angfsm_%s_next_t;\n\n", fsm->name);
+
+ /* Gen transition structure. */
+ fprintf (f, "typedef struct\n{\n");
+ fprintf (f, "\tangfsm_%s_event_t event;\n", fsm->name);
+ fprintf (f, "\tangfsm_%s_func_t func;\n", fsm->name);
+ fprintf (f, "\tangfsm_%s_next_t branches[angfsm_%s_max_branches_per_trans];\n",
+ fsm->name,
fsm->name);
- fprintf (f, "extern const angfsm_%s_func_t PROGMEM angfsm_%s_trans_table[%u][%u];\n",
+ fprintf (f, "} angfsm_%s_trans_t;\n\n", fsm->name);
+
+ /* Gen transition table. */
+ fprintf (f, "extern const angfsm_%s_trans_t PROGMEM angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states];\n\n",
+ fsm->name,
fsm->name,
fsm->name,
- fsm->event_nb,
- fsm->state_nb);
+ fsm->name);
+
/* Gen read function for trans table. */
- fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, "
- "angfsm_%s_state_t state);\n\n",
+ fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans (angfsm_%s_event_t event, angfsm_%s_state_t state);\n\n",
fsm->name,
fsm->name,
fsm->name,
fsm->name);
/* Gen active states array. */
- fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n",
+ fprintf (f, "extern angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n",
fsm->name,
fsm->name,
- fsm->max_active_states);
+ fsm->name);
/* Gen initialization function. */
sc = fsm->starters;
@@ -1899,20 +2116,20 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fsm->name);
/* Gen timeout values. */
- fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_];\n",
+ fprintf (f, "extern int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB];\n",
fsm->name,
fsm->name);
/* Gen timeout corresponding events. */
- fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_];\n",
+ fprintf (f, "extern angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB];\n",
fsm->name,
fsm->name,
fsm->name);
/* Gen timeout counters array. */
- fprintf (f, "extern int32_t angfsm_%s_timeout_counters[%u];\n\n",
+ fprintf (f, "extern int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n\n",
fsm->name,
- fsm->max_active_states);
+ fsm->name);
}
/* Conclusion. */
@@ -1926,14 +2143,16 @@ angfsm_build_gen_opti_avr_h (angfsm_build_t *fsm, angfsm_build_arch_t arch)
void
angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
{
+ assert (fsm);
assert (arch < ANGFSM_BUILD_ARCH_NB);
angfsm_build_state_chain_t *sc;
angfsm_build_event_chain_t *ec;
angfsm_build_trans_chain_t *tc;
angfsm_build_timeout_chain_t *toc;
+ angfsm_build_branch_chain_t *bc;
angfsm_build_state_t *s;
angfsm_build_event_t *e;
- uint i, j, found;
+ uint i, j, k, count;
uint embedded_strings = fsm->options.embedded_strings;
/* Open file. */
@@ -1950,9 +2169,10 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
angfsm_build_arch_name[arch],
fsm->name);
- /* Gen state strings. */
+ /* Gen strings if configured. */
if (embedded_strings)
{
+ /* Gen state strings. */
sc = fsm->states;
while (sc != NULL)
{
@@ -1996,6 +2216,25 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
}
fprintf (f, "};\n\n");
+ /* Gen branch strings. */
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ {
+ fprintf (f, "prog_char angfsm_%s_branch_str_%s[] PROGMEM = \"%s\";\n",
+ fsm->name,
+ fsm->u_branch_name[i],
+ fsm->u_branch_name[i]);
+ }
+ fprintf (f, "const char *angfsm_%s_branch_str[] PROGMEM =\n{\n", fsm->name);
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ {
+ fprintf (f, "\tangfsm_%s_branch_str_%s", fsm->name, fsm->u_branch_name[i]);
+ if (i == fsm->u_branch_nb - 1)
+ fprintf (f, "\n");
+ else
+ fprintf (f, ",\n");
+ }
+ fprintf (f, "};\n\n");
+
/* Create a RAM string able to store event or state string. */
j = 0;
for (i = 0; i < fsm->event_nb; i++)
@@ -2010,106 +2249,152 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
if (strlen (s->var_name) > j)
j = strlen (s->var_name);
}
+ for (i = 0; i < fsm->u_branch_nb; i++)
+ {
+ if (strlen (fsm->u_branch_name[i]) > j)
+ j = strlen (fsm->u_branch_name[i]);
+ }
fprintf (f, "char angfsm_%s_str_buff[%u];\n", fsm->name, j + 1);
+ /* Generate string read functions. */
/* Convert an event enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_event_string_from_enum \
+ fprintf (f, "char *\nangfsm_%s_get_event_str \
(angfsm_%s_event_t e)\n{\n", fsm->name, fsm->name);
fprintf (f, "\treturn strcpy_P (angfsm_%s_str_buff, \
(char *) pgm_read_word (&(angfsm_%s_event_str[e])));\n", fsm->name, fsm->name);
fprintf (f, "}\n\n");
-
- /* Convert a event string in enum. */
- fprintf (f, "angfsm_%s_event_t\nangfsm_%s_get_event_enum_from_string \
- (char *str)\n{\n", fsm->name, fsm->name);
- fprintf (f, "\tuint16_t i;\n");
- fprintf (f, "\tfor (i = 0; i < angfsm_EVENT_%s_NB_; i++)\n", fsm->name);
- fprintf (f, "\t\tif (strcpy_P (str, \
- (char *) pgm_read_word (&(angfsm_%s_event_str[i]))) == 0)\n", fsm->name);
- fprintf (f, "\t\t\treturn i;\n");
- fprintf (f, "\treturn angfsm_EVENT_%s_NB_;\n", fsm->name);
- fprintf (f, "}\n\n");
-
- /* Convert an state enum in string. */
- fprintf (f, "char *\nangfsm_%s_get_state_string_from_enum \
+ /* Convert a state enum in string. */
+ fprintf (f, "char *\nangfsm_%s_get_state_str \
(angfsm_%s_state_t s)\n{\n", fsm->name, fsm->name);
fprintf (f, "\treturn strcpy_P (angfsm_%s_str_buff, \
(char *) pgm_read_word (&(angfsm_%s_state_str[s])));\n", fsm->name, fsm->name);
fprintf (f, "}\n\n");
-
- /* Convert a state string in enum. */
- fprintf (f, "angfsm_%s_state_t\nangfsm_%s_get_state_enum_from_string \
- (char *str)\n{\n", fsm->name, fsm->name);
- fprintf (f, "\tuint16_t i;\n");
- fprintf (f, "\tfor (i = 0; i < angfsm_STATE_%s_NB_; i++)\n", fsm->name);
- fprintf (f, "\t\tif (strcpy_P (str, \
- (char *) pgm_read_word (&(angfsm_%s_state_str[i]))) == 0)\n", fsm->name);
- fprintf (f, "\t\t\treturn i;\n");
- fprintf (f, "\treturn angfsm_STATE_%s_NB_;\n", fsm->name);
+ /* Convert a branch enum in string. */
+ fprintf (f, "char *\nangfsm_%s_get_branch_str \
+ (angfsm_%s_branch_t b)\n{\n", fsm->name, fsm->name);
+ fprintf (f, "\treturn strcpy_P (angfsm_%s_str_buff, \
+ (char *) pgm_read_word (&(angfsm_%s_branch_str[b])));\n", fsm->name, fsm->name);
fprintf (f, "}\n\n");
}
- /* Gen function table. */
- fprintf (f, "const angfsm_%s_func_t PROGMEM angfsm_%s_trans_table[%u][%u] = \n{\n",
+ /* Gen transition table. */
+ fprintf (f, "const angfsm_%s_trans_t PROGMEM angfsm_%s_trans_table[angfsm_STATE_%s_NB][angfsm_%s_max_events_per_states] = \n{\n",
fsm->name,
fsm->name,
- fsm->event_nb,
- fsm->state_nb);
- /* for each events and state, see if it exists an associated transition. */
- for (i = 0; i < fsm->event_nb; i++)
+ fsm->name,
+ fsm->name);
+ for (i = 0; i < fsm->state_nb; i++)
{
- e = angfsm_build_get_event_by_code (fsm, i);
- fprintf (f, "\t{");
- for (j = 0; j < fsm->state_nb; j++)
+ count = 0;
+ fprintf (f, "\t{\n");
+ tc = fsm->trans;
+ while (tc != NULL)
{
- s = angfsm_build_get_state_by_code (fsm, j);
- tc = fsm->trans;
- found = 0;
- while (tc != NULL)
- {
- if (tc->trans.state == s && tc->trans.event == e)
- {
- found = 1;
- fprintf (f, "&angfsm_%s_trans_func_%s_%s",
- fsm->name,
- tc->trans.state->var_name,
- tc->trans.event->var_name);
- tc = tc->next;
- break;
- }
- tc = tc->next;
- }
- if (!found)
- fprintf (f, "(angfsm_%s_func_t) 0", fsm->name);
- if (j == fsm->state_nb - 1)
- fprintf (f, "}");
- else
- fprintf (f, ", ");
+ if (tc->trans.state->code == i)
+ {
+ fprintf (f, "\t\t{\n");
+ fprintf (f, "\t\t\tangfsm_EVENT_%s_%s,\n",
+ fsm->name,
+ tc->trans.event->var_name);
+ fprintf (f, "\t\t\t(angfsm_%s_func_t) &angfsm_%s_trans_func_%s_%s,\n",
+ fsm->name,
+ fsm->name,
+ tc->trans.state->var_name,
+ tc->trans.event->var_name);
+ /* Gen branche array */
+ fprintf (f, "\t\t\t{\n");
+ j = 0;
+ bc = tc->trans.output_branches;
+ while (bc != NULL)
+ {
+ fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_%s, angfsm_STATE_%s_%s}",
+ fsm->name,
+ (bc->name ? bc->name : "NB"),
+ fsm->name,
+ bc->state->var_name);
+ if (j != fsm->max_branches_per_trans - 1)
+ fprintf (f, ", ");
+ fprintf (f, "\n");
+ j++;
+ bc = bc->next;
+ }
+ /* Fill blank branches. */
+ for (k = j; k < fsm->max_branches_per_trans; k++)
+ {
+ fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}",
+ fsm->name,
+ fsm->name);
+ if (k != fsm->max_branches_per_trans - 1)
+ fprintf (f, ",");
+ fprintf (f, "\n");
+ }
+
+ fprintf (f, "\t\t\t}\n");
+ if (tc->next != NULL || count != fsm->max_events_per_states)
+ fprintf (f, "\t\t},\n");
+ else
+ fprintf (f, "\t\t}\n");
+ count++;
+ }
+ tc = tc->next;
}
- if (i != fsm->event_nb - 1)
- fprintf (f, ",");
- fprintf (f, "\n");
+ /* Fill blanch transitions. */
+ for (k = count; k < fsm->max_events_per_states; k++)
+ {
+ fprintf (f, "\t\t{\n");
+ fprintf (f, "\t\t\tangfsm_EVENT_%s_NB,\n",fsm->name);
+ fprintf (f, "\t\t\t(angfsm_%s_func_t) 0,\n", fsm->name);
+ fprintf (f, "\t\t\t{\n");
+ for (j = 0; j < fsm->max_branches_per_trans; j++)
+ {
+ fprintf (f, "\t\t\t\t{angfsm_BRANCH_%s_NB, angfsm_STATE_%s_NB}",
+ fsm->name,
+ fsm->name);
+ if (j != fsm->max_branches_per_trans - 1)
+ fprintf (f, ",");
+ fprintf (f, "\n");
+ }
+ fprintf (f, "\t\t\t}\n");
+ if (k != fsm->max_events_per_states - 1)
+ fprintf (f, "\t\t},\n");
+ else
+ fprintf (f, "\t\t}\n");
+ }
+
+ if (i == fsm->state_nb - 1)
+ fprintf (f, "\t}\n");
+ else
+ fprintf (f, "\t},\n");
}
fprintf (f, "};\n\n");
- /* Gen read function for trans table. */
- fprintf (f, "angfsm_%s_func_t angfsm_%s_read_trans (angfsm_%s_event_t event, "
- "angfsm_%s_state_t state)\n{\n",
- fsm->name,
- fsm->name,
+ /* Transition callback. */
+ fprintf (f, "void (*angfsm_%s_trans_callback) (int state, int event, int output_branch, int branch);\n", fsm->name);
+
+ /* Gen active states array. */
+ fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[angfsm_%s_max_active_states];\n\n",
fsm->name,
- fsm->name);
- fprintf (f, "\treturn (angfsm_%s_func_t) pgm_read_word "
- "(&angfsm_%s_trans_table[event][state]);\n",
fsm->name,
fsm->name);
- fprintf (f, "}\n\n");
- /* Gen active states array. */
- fprintf (f, "angfsm_%s_state_t angfsm_%s_active_states[%u];\n\n",
+ /* Gen read transition from event and state. */
+ fprintf (f, "inline angfsm_%s_trans_t* angfsm_%s_read_trans "
+ "(angfsm_%s_event_t event, angfsm_%s_state_t state)\n{\n",
fsm->name,
fsm->name,
- fsm->max_active_states);
+ fsm->name,
+ fsm->name);
+ fprintf (f, "\tint i;\n");
+ fprintf (f, "\tangfsm_%s_trans_t* t;\n", fsm->name);
+ fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_events_per_states; i++)\n\t{\n",
+ fsm->name);
+ fprintf (f, "\t\tt = (angfsm_%s_trans_t *) pgm_read_word (&angfsm_%s_trans_table[state][i]);\n",
+ fsm->name,
+ fsm->name);
+ fprintf (f, "\t\tif (t->func == (angfsm_%s_func_t) 0)\n\t\t\tbreak;\n", fsm->name);
+ fprintf (f, "\t\tif (t->event == event)\n");
+ fprintf (f, "\t\t\treturn t;\n");
+ fprintf (f, "\t}\n\treturn (angfsm_%s_trans_t*) 0;\n}\n\n", fsm->name);
/* Gen initialization function. */
sc = fsm->starters;
@@ -2117,11 +2402,11 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "void\nangfsm_%s_init ()\n{\n", fsm->name);
while (sc != NULL)
{
- fprintf (f, "\tangfsm_%s_active_states[%u] = (angfsm_%s_state_t) %u;\n",
+ fprintf (f, "\tangfsm_%s_active_states[%u] = angfsm_STATE_%s_%s;\n",
fsm->name,
i,
fsm->name,
- sc->state.code);
+ sc->state.var_name);
if (fsm->timeouts != NULL)
{
toc = fsm->timeouts;
@@ -2140,23 +2425,43 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
i++;
sc = sc->next;
}
+ /* Set transition callback to NULL. */
+ fprintf (f, "\tangfsm_%s_trans_callback = (typeof (angfsm_%s_trans_callback)) 0;\n", fsm->name, fsm->name);
fprintf (f, "}\n\n");
/* Gen handle function. */
fprintf (f, "int\nangfsm_%s_handle (angfsm_%s_event_t e)\n{\n",
fsm->name,
fsm->name);
- fprintf (f, "\tuint16_t i;\n");
+ fprintf (f, "\tuint16_t i, j;\n");
fprintf (f, "\tint handled = 0;\n");
+ fprintf (f, "\tangfsm_%s_branch_t b;\n", fsm->name);
fprintf (f, "\tfor (i = 0; i < angfsm_%s_max_active_states; i++)\n\t{\n",
fsm->name);
- fprintf (f, "\t\tangfsm_%s_func_t trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n",
+ fprintf (f, "\t\tangfsm_%s_trans_t *trans = angfsm_%s_read_trans (e, angfsm_%s_active_states[i]);\n",
fsm->name,
fsm->name,
fsm->name);
fprintf (f, "\t\tif (trans)\n");
fprintf (f, "\t\t{\n");
- fprintf (f, "\t\t\tangfsm_%s_active_states[i] = (angfsm_%s_state_t) trans ();\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\tangfsm_%s_state_t s = angfsm_STATE_%s_NB;\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\tif (trans->branches[0].branch == angfsm_BRANCH_%s_NB)\n\t\t\t{\n", fsm->name);
+ fprintf (f, "\t\t\t\ttrans->func ();\n");
+ fprintf (f, "\t\t\t\ts = trans->branches[0].state;\n");
+ fprintf (f, "\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name);
+ fprintf (f, "\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, -1);\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\t}\n\t\t\telse\n\t\t\t{\n");
+ fprintf (f, "\t\t\t\tb = ((angfsm_%s_func_branches_t) trans->func) ();\n", fsm->name);
+ fprintf (f, "\t\t\t\tfor (j = 0; j < angfsm_%s_max_branches_per_trans; j++)\n", fsm->name);
+ fprintf (f, "\t\t\t\t\tif (trans->branches[j].branch == b)\n");
+ fprintf (f, "\t\t\t\t\t\ts = trans->branches[j].state;\n");
+ fprintf (f, "\t\t\t\t\tif (angfsm_%s_trans_callback)\n", fsm->name);
+ fprintf (f, "\t\t\t\t\t\tangfsm_%s_trans_callback(angfsm_%s_active_states[i], e, s, b);\n", fsm->name, fsm->name);
+ fprintf (f, "\t\t\t}\n");
+ fprintf (f, "\t\t\tif (s != angfsm_STATE_%s_NB)\n", fsm->name);
+ fprintf (f, "\t\t\t\tangfsm_%s_active_states[i] = s;\n", fsm->name);
+ fprintf (f, "\t\t\telse\n");
+ fprintf (f, "\t\t\t\t{;} //XXX show some error ?\n");
fprintf (f, "\t\t\thandled = 1;\n");
if (fsm->timeouts != NULL)
{
@@ -2188,12 +2493,12 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
if (fsm->timeouts != NULL)
{
/* Gen timeout counters array. */
- fprintf (f, "int32_t angfsm_%s_timeout_counters[%u];\n",
+ fprintf (f, "int32_t angfsm_%s_timeout_counters[angfsm_%s_max_active_states];\n",
fsm->name,
- fsm->max_active_states);
+ fsm->name);
/* Gen timeout values array. */
- fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB_] =\n{\n",
+ fprintf (f, "int32_t angfsm_%s_timeout_values[angfsm_STATE_%s_NB] =\n{\n",
fsm->name,
fsm->name);
int value;
@@ -2220,7 +2525,7 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
fprintf (f, "};\n\n");
/* Gen timeout corresponding events array. */
- fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB_] =\n{\n",
+ fprintf (f, "angfsm_%s_event_t angfsm_%s_timeout_events[angfsm_STATE_%s_NB] =\n{\n",
fsm->name,
fsm->name,
fsm->name);
@@ -2240,7 +2545,7 @@ angfsm_build_gen_opti_avr_c (angfsm_build_t *fsm, angfsm_build_arch_t arch)
toc = toc->next;
}
if (value == -1)
- fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB_", fsm->name, fsm->name);
+ fprintf (f, "\t(angfsm_%s_event_t) angfsm_STATE_%s_NB", fsm->name, fsm->name);
else
fprintf (f, "\t(angfsm_%s_event_t) %u", fsm->name, value);
@@ -2429,6 +2734,11 @@ angfsm_build_free (angfsm_build_t *fsm)
free (toc_tmp);
}
+ /* Free unique branch names array. */
+ /* Strings are already free in transitions. */
+ if (fsm->u_branch_name)
+ free (fsm->u_branch_name);
+
/* Free run data (trans_table). */
for (i = 0; i < fsm->event_nb; i++)
free (fsm->run.trans_table[i]);
@@ -2452,5 +2762,3 @@ angfsm_build_free (angfsm_build_t *fsm)
/*Free run data (timeout counters). */
free (fsm->run.timeout_counters);
}
-
-#endif /* HOST */
diff --git a/digital/ai/src/fsm/angfsm_generic.h b/digital/ai/src/fsm/angfsm_generic.h
index 4e1c589f..f2840beb 100644
--- a/digital/ai/src/fsm/angfsm_generic.h
+++ b/digital/ai/src/fsm/angfsm_generic.h
@@ -1,6 +1,6 @@
/*
AngFSM - Almost Non Generated Finite State Machine
- Copyright 2011, 2012 Jerome Jutteau
+ Copyright 2011-2013 Jerome Jutteau
This file is part of AngFSM.
@@ -50,9 +50,7 @@
/** Disable dot generation. */
#define ANGFSM_GEN_DOT(fsm, output)
-/** Disable state defining
- *
- * Define states of the fsm, can be called several times to add other states. */
+/** Disable state defining */
#define ANGFSM_STATES(states...)
/** Disable event defining */
@@ -62,28 +60,52 @@
#define ANGFSM_START_WITH(starters...)
#define ANGFSM_TRANS(state, event, output_branches...) \
- ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_branch_t) \
- ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_trans_func_##state##_##event) ()
+ IFELSE_ARG1(void, ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_branch_t), output_branches) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_trans_func_##state##_##event) ()
-#define ANGFSM_NEXT(state, event, branch...) \
- ANGFSM_PASTE3_EXPAND (angfsm_BRANCH_, ANGFSM_NAME,_##state##_##event##_##branch)
+/** Transform an event in a numeric value. */
+#define ANGFSM_EVENT(event) (ANGFSM_PASTE3_EXPAND (angfsm_EVENT_,ANGFSM_NAME,_##event))
+#define ANGFSM_EVENT_F(fsm, event) angfsm_EVENT_##fsm##_##event
-/** Transform an event in uint16_t. */
-#define ANGFSM_EVENT(fsm, event) angfsm_EVENT_##fsm##_##event
+/** Transform a state in a numeric value. */
+#define ANGFSM_STATE(state) (ANGFSM_PASTE3_EXPAND (angfsm_STATE_,ANGFSM_NAME,_##state))
+#define ANGFSM_STATE_F(fsm, state) angfsm_STATE_##fsm##_##state
-/** Handle event from uint16_t. */
+/** Transform a branch in a numeric value. */
+#define ANGFSM_BRANCH(branch) (ANGFSM_PASTE3_EXPAND (angfsm_BRANCH_,ANGFSM_NAME,_##branch))
+#define ANGFSM_BRANCH_F(fsm, branch) angfsm_BRANCH_##fsm##_##branch
+
+/** Handle event from numeric event. */
#define ANGFSM_HANDLE_VAR(fsm, event) angfsm_##fsm##_handle (event)
-/* Can we handle event from uint16_t ? */
+/* Can we handle event from numeric event ? */
#define ANGFSM_CAN_HANDLE_VAR(fsm, event) angfsm_##fsm##_can_handle (event)
/* Time out macros. */
#define ANGFSM_TRANS_TIMEOUT(state, timeout, output_branches...) \
ANGFSM_TRANS (state, state##_TIMEOUT, output_branches)
-#define ANGFSM_NEXT_TIMEOUT(state, branch...) \
- ANGFSM_NEXT (state, state##_TIMEOUT, branch)
-
#define ANGFSM_HANDLE_TIMEOUT(fsm_name) angfsm_##fsm_name##_handle_timeout ()
-#endif \ No newline at end of file
+/* Callback for transitions. */
+#define ANGFSM_TRANS_CALLBACK(cb) \
+ ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_trans_callback) = cb;
+
+/* Get state string.
+ * This macro is disabled if strings has no been embedded.
+ */
+#define ANGFSM_STATE_STR(state) \
+ ((char *) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_get_state_str (state)))
+
+/* Get event string.
+ * This macro is disabled if strings has no been embedded.
+ */
+#define ANGFSM_EVENT_STR(event) \
+ ((char *) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_get_event_str (event)))
+
+/* Get branch string.
+ * This macro is disabled if strings has no been embedded.
+ */
+#define ANGFSM_BRANCH_STR(branch) \
+ ((char *) ANGFSM_PASTE3_EXPAND (angfsm_, ANGFSM_NAME,_get_branch_str (branch)))
+
+#endif
diff --git a/digital/ai/src/fsm/angfsm_host_exec.h b/digital/ai/src/fsm/angfsm_host_exec.h
index 956ef4ed..8fac0a42 100644
--- a/digital/ai/src/fsm/angfsm_host_exec.h
+++ b/digital/ai/src/fsm/angfsm_host_exec.h
@@ -1,6 +1,6 @@
/*
AngFSM - Almost Non Generated Finite State Machine
- Copyright 2011, 2012 Jerome Jutteau
+ Copyright 2011-2013 Jerome Jutteau
This file is part of AngFSM.
@@ -103,8 +103,15 @@ typedef struct angfsm_build_trans_chain_t {
struct angfsm_build_trans_chain_t *next;
} angfsm_build_trans_chain_t;
-/* Pointer to a transition function. */
-typedef angfsm_build_state_t* (*angfsm_build_run_strans_func_t)(void);
+/* Pointer to a transition function.
+ * out_branch corresponds to function's return.
+ * Mono branch transitions do not return anything,
+ * It permits to avoid ugly warnings.
+ * Multi branches returns a uint, the function is transtyped as a
+ * angfsm_build_run_strans_func_branches_t
+ */
+typedef void (*angfsm_build_run_strans_func_t) ();
+typedef uint (*angfsm_build_run_strans_func_branches_t) ();
/* Chain of transitions with associated function's pointer. */
typedef struct angfsm_trans_func_chain_t {
@@ -146,6 +153,11 @@ typedef struct {
/* Array of counters for timeout events.
* -1 mean counter is off. */
int *timeout_counters;
+ /* Callback to transitions. */
+ void (*trans_callback) (int state,
+ int event,
+ int output_branch,
+ int branch);
} angfsm_build_run_t;
/* Store all Finite State Machine (fsm) informations. */
@@ -160,6 +172,10 @@ typedef struct {
char *name;
/* Maximal number of active states. */
uint max_active_states;
+ /* Maximal number of events per states. */
+ uint max_events_per_states;
+ /* Maximal number of branches per transitions. */
+ uint max_branches_per_trans;
/* Total number of events. */
uint event_nb;
/* Total number of states. */
@@ -168,6 +184,13 @@ typedef struct {
angfsm_build_state_chain_t *starters;
/* All timeout. */
angfsm_build_timeout_chain_t *timeouts;
+ /* Total number of unique branch name. */
+ uint u_branch_nb;
+ /* List of unique branches strings.
+ * Unique number corresponding to string is the position of the string
+ *in the array.
+ */
+ char **u_branch_name;
/* Data for running purposes. */
angfsm_build_run_t run;
/* User's options. */
@@ -189,7 +212,8 @@ void angfsm_build_init_all_fsm() __attribute__((constructor(101)));
* function. This permits initilialization of the fsm. */
extern angfsm_build_t ANGFSM_PASTE_EXPAND(angfsm_, ANGFSM_NAME);
void ANGFSM_PASTE_EXPAND(angfsm_build_init_, ANGFSM_NAME)() __attribute__((constructor(102)));
-void ANGFSM_PASTE_EXPAND(angfsm_build_run_init_, ANGFSM_NAME)() __attribute__((constructor(107)));
+void ANGFSM_PASTE_EXPAND(angfsm_build_init_finalize_, ANGFSM_NAME)() __attribute__((constructor(107)));
+void ANGFSM_PASTE_EXPAND(angfsm_build_run_init_, ANGFSM_NAME)() __attribute__((constructor(108)));
void ANGFSM_PASTE_EXPAND(angfsm_build_free_, ANGFSM_NAME)() __attribute__((destructor));
#define ANGFSM_INIT \
@@ -198,6 +222,10 @@ void ANGFSM_PASTE_EXPAND(angfsm_build_free_, ANGFSM_NAME)() __attribute__((destr
{ \
angfsm_build_init (ANGFSM_PASTE_EXPAND (&angfsm_, ANGFSM_NAME), XSTR(ANGFSM_NAME)); \
} \
+ void ANGFSM_PASTE_EXPAND (angfsm_build_init_finalize_, ANGFSM_NAME)() \
+ { \
+ angfsm_build_init_finalize (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)); \
+ } \
void ANGFSM_PASTE_EXPAND (angfsm_build_run_init_, ANGFSM_NAME)() \
{ \
angfsm_build_run_init (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)); \
@@ -262,23 +290,14 @@ extern angfsm_build_t angfsm_##fsm_name;
* See examples for reel usage.
*/
#define ANGFSM_TRANS(state, event, output_branches...) \
-angfsm_build_state_t* ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) (); \
+ IFELSE_ARG1(void, uint, output_branches) ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) (); \
void ANGFSM_PASTE3_EXPAND (angfsm_build_trans_, ANGFSM_NAME,_##state##_##event)() __attribute__((constructor(105))); \
void ANGFSM_PASTE3_EXPAND (angfsm_build_trans_, ANGFSM_NAME,_##state##_##event)() \
{ \
- angfsm_build_trans (& ANGFSM_PASTE_EXPAND(angfsm_, ANGFSM_NAME), #state, #event, \
- #output_branches, \
- & ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event)); \
+ angfsm_build_trans (& ANGFSM_PASTE_EXPAND(angfsm_, ANGFSM_NAME), #state, #event, #output_branches, \
+ (angfsm_build_run_strans_func_t) &ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event)); \
} \
- angfsm_build_state_t* ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) ()
-
-/**
- * Used to return next state by giving the actual transition informations and
- * the branch (if there are several branches).
- * Not directly returning the state can avoid some errors. *
- */
-#define ANGFSM_NEXT(state, event, branch...) \
- angfsm_build_get_next_state (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #state, #event, #branch)
+ IFELSE_ARG1(void, uint, output_branches) ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state##_##event) ()
/**
* Define a transition when a state times out.
@@ -296,28 +315,51 @@ angfsm_build_state_t* ANGFSM_PASTE3_EXPAND (angfsm_trans_, ANGFSM_NAME,_##state#
ANGFSM_EVENTS (state##_TIMEOUT) \
ANGFSM_TRANS (state, state##_TIMEOUT, output_branches)
-/**
- * Used to return next state after a timeout.
- * Same as ANGFSM_NEXT but without specifying an event.
- */
-#define ANGFSM_NEXT_TIMEOUT(state, branch...) \
- ANGFSM_NEXT (state, state##_TIMEOUT, branch)
-
/** Used to handle timeout events. */
#define ANGFSM_HANDLE_TIMEOUT(fsm_name) \
- angfsm_build_handle_timeout (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME))
+ (angfsm_build_handle_timeout (& angfsm_##fsm_name))
+
+/** Transform an event in a numeric value. */
+#define ANGFSM_EVENT(event) \
+ (angfsm_build_get_event_code (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #event))
+#define ANGFSM_EVENT_F(fsm_name, event) \
+ (angfsm_build_get_event_code (& angfsm_##fsm_name, #event))
+
+/** Transform a state in a numeric value. */
+#define ANGFSM_STATE(state) \
+ (angfsm_build_get_state (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #state)->code)
+#define ANGFSM_STATE_F(fsm_name, state) \
+ (angfsm_build_get_state (& angfsm_##fsm_name, #state)->code)
+
+/** Transform a branch in a numeric value. */
+#define ANGFSM_BRANCH(branch) \
+ (angfsm_build_get_branch (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #branch))
+#define ANGFSM_BRANCH_F(fsm_name, branch) \
+ (angfsm_build_get_branch (& angfsm_##fsm_name, #branch))
+
+/** Handle event from numeric value. */
+#define ANGFSM_HANDLE_VAR(fsm, event) \
+ angfsm_build_handle_integer (& angfsm_##fsm, event)
-/** Transform an event in uint16_t. */
-#define ANGFSM_EVENT(fsm_name, event) \
- angfsm_build_get_event_code (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), #event)
+/* Can we handle event from numeric value ? */
+#define ANGFSM_CAN_HANDLE_VAR(fsm, event) \
+ angfsm_build_can_handle_integer (& angfsm_##fsm, event)
-/** Handle event from uint16_t. */
-#define ANGFSM_HANDLE_VAR(fsm, event) \
- angfsm_build_handle_integer (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), event)
+/* Callback for transitions. */
+#define ANGFSM_TRANS_CALLBACK(cb) \
+ ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME).run.trans_callback = cb
-/* Can we handle event from uint16_t ? */
-#define ANGFSM_CAN_HANDLE_VAR(fSM, event) \
- angfsm_build_can_handle_integer (& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME), event)
+/* Get state string. */
+#define ANGFSM_STATE_STR(state) \
+ ((char *)((angfsm_build_get_state_by_code((& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)), state))->var_name))
+
+/* Get event string. */
+#define ANGFSM_EVENT_STR(event) \
+ ((char *)((angfsm_build_get_event_by_code((& ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME)), event))->var_name))
+
+/* Get branch string. */
+#define ANGFSM_BRANCH_STR(branch) \
+ ((char *)(ANGFSM_PASTE_EXPAND (angfsm_, ANGFSM_NAME).u_branch_name[branch]))
/**
* Parse a string who contains a list of arguments separated by comma.
@@ -339,15 +381,15 @@ void
angfsm_build_arg_free(char ***tab, int nb);
/**
- * This function is executed when a state is returned by a transition.
+ * Print transition.
* \param fsm fsm
* \param trans transition where the return occurs
* \param branch branch to transition has chosen.
*/
void
-angfsm_build_print(angfsm_build_t *fsm,
- angfsm_build_trans_t* trans,
- angfsm_build_branch_chain_t* branch);
+angfsm_build_print_trans (angfsm_build_t *fsm,
+ angfsm_build_trans_t* trans,
+ angfsm_build_branch_chain_t* branch);
/**
* Test the fsm and search for errors.
@@ -371,6 +413,10 @@ angfsm_build_gen_dot(angfsm_build_t *fsm, char *output);
void
angfsm_build_init(angfsm_build_t *fsm, char *name);
+/** Finalize the preparation of the FSM informations. */
+void
+angfsm_build_init_finalize (angfsm_build_t *fsm);
+
/** Initialize the running data of the fsm. */
void
angfsm_build_run_init(angfsm_build_t *fsm);
@@ -407,10 +453,24 @@ angfsm_build_get_event_by_code(angfsm_build_t *fsm, uint event);
angfsm_build_state_t*
angfsm_build_get_state_by_code(angfsm_build_t *fsm, uint state);
-/** Get event code as uint16_t */
+/** Get transition pointer by giving it's state and event. */
+angfsm_build_trans_t*
+angfsm_build_get_trans (angfsm_build_t *fsm, uint state, uint event);
+
+/** Get event code as a numeric value. */
uint16_t
angfsm_build_get_event_code(angfsm_build_t *fsm, char *event);
+/** Get branch pointer from transition and branch string. */
+angfsm_build_branch_chain_t*
+angfsm_build_get_event_branch (angfsm_build_t *fsm,
+ angfsm_build_trans_t *trans,
+ uint branch);
+
+/** Get branch unique code from branch name. */
+uint
+angfsm_build_get_branch (angfsm_build_t *fsm, char *branch);
+
/**
* Add a transition to the fsm.
* \param fsm fsm
@@ -482,13 +542,6 @@ angfsm_build_can_handle_integer(angfsm_build_t *fsm, uint16_t event);
int
angfsm_build_handle_timeout(angfsm_build_t *fsm);
-/** Give the state at the transition output. */
-angfsm_build_state_t*
-angfsm_build_get_next_state(angfsm_build_t *fsm,
- char *state,
- char *event,
- char *branch);
-
/** Pass parameters to AngFSM at execution. Try --ang-help
* \param argc argc from your main.
* \param argv argv from your main.
diff --git a/digital/ai/src/fsm/angfsm_renaming.h b/digital/ai/src/fsm/angfsm_renaming.h
index 393fad42..f50f692e 100644
--- a/digital/ai/src/fsm/angfsm_renaming.h
+++ b/digital/ai/src/fsm/angfsm_renaming.h
@@ -28,18 +28,25 @@
#define FSM_HANDLE ANGFSM_HANDLE
#define FSM_CAN_HANDLE ANGFSM_CAN_HANDLE
#define FSM_RESET ANGFSM_RESET
-#define FSM_GEN_DOTANGFSM_GEN_DOT
+#define FSM_GEN_DOT ANGFSM_GEN_DOT
#define FSM_STATES ANGFSM_STATES
#define FSM_EVENTS ANGFSM_EVENTS
#define FSM_START_WITH ANGFSM_START_WITH
#define FSM_TRANS ANGFSM_TRANS
-#define FSM_NEXT ANGFSM_NEXT
+#define FSM_STATE ANGFSM_STATE
#define FSM_EVENT ANGFSM_EVENT
+#define FSM_BRANCH ANGFSM_BRANCH
+#define FSM_STATE_F ANGFSM_STATE_F
+#define FSM_EVENT_F ANGFSM_EVENT_F
+#define FSM_BRANCH_F ANGFSM_BRANCH_F
#define FSM_HANDLE_VAR ANGFSM_HANDLE_VAR
#define FSM_CAN_HANDLE_VAR ANGFSM_CAN_HANDLE_VAR
#define FSM_TRANS_TIMEOUT ANGFSM_TRANS_TIMEOUT
-#define FSM_NEXT_TIMEOUT ANGFSM_NEXT_TIMEOUT
#define FSM_HANDLE_TIMEOUT ANGFSM_HANDLE_TIMEOUT
-
+#define FSM_TRANS_CALLBACK ANGFSM_TRANS_CALLBACK
+#define FSM_STATE_STR ANGFSM_STATE_STR
+#define FSM_EVENT_STR ANGFSM_EVENT_STR
+#define FSM_BRANCH_STR ANGFSM_BRANCH_STR
+
#endif /* #ifdef _ANGFSM_RENAME_ */
diff --git a/digital/ai/src/fsm/init.c b/digital/ai/src/fsm/init.c
index 72479a32..00c5a08f 100644
--- a/digital/ai/src/fsm/init.c
+++ b/digital/ai/src/fsm/init.c
@@ -88,61 +88,52 @@ FSM_START_WITH (INIT_START)
FSM_TRANS (INIT_START, jack_inserted, INIT_WAITING_FIRST_JACK_OUT)
{
- return FSM_NEXT (INIT_START, jack_inserted);
}
FSM_TRANS (INIT_WAITING_FIRST_JACK_OUT, jack_removed,
INIT_INITIALISING_ACTUATORS)
{
- fsm_queue_post_event (FSM_EVENT (AI, init_actuators));
- return FSM_NEXT (INIT_WAITING_FIRST_JACK_OUT, jack_removed);
+ fsm_queue_post_event (FSM_EVENT (init_actuators));
}
FSM_TRANS (INIT_INITIALISING_ACTUATORS, jack_inserted, INIT_WAITING_HANDS_OUT)
{
team_color = contact_get_color ();
- return FSM_NEXT (INIT_INITIALISING_ACTUATORS, jack_inserted);
}
FSM_TRANS_TIMEOUT (INIT_WAITING_HANDS_OUT, 225, INIT_FINDING_FIRST_WALL)
{
asserv_set_speed (BOT_SPEED_INIT);
asserv_push_the_wall (INIT_FIRST_WALL_PUSH);
- return FSM_NEXT_TIMEOUT (INIT_WAITING_HANDS_OUT);
}
FSM_TRANS (INIT_FINDING_FIRST_WALL, robot_move_success,
INIT_GOING_AWAY_FIRST_WALL)
{
asserv_move_linearly (INIT_FIRST_WALL_AWAY);
- return FSM_NEXT (INIT_FINDING_FIRST_WALL, robot_move_success);
}
FSM_TRANS (INIT_GOING_AWAY_FIRST_WALL, robot_move_success,
INIT_FACING_SECOND_WALL)
{
asserv_goto_angle (INIT_SECOND_WALL_ANGLE);
- return FSM_NEXT (INIT_GOING_AWAY_FIRST_WALL, robot_move_success);
}
FSM_TRANS (INIT_FACING_SECOND_WALL, robot_move_success,
INIT_WAITING_AFTER_FACING_SECOND_WALL)
{
- return FSM_NEXT (INIT_FACING_SECOND_WALL, robot_move_success);
}
FSM_TRANS_TIMEOUT (INIT_WAITING_AFTER_FACING_SECOND_WALL, 225 / 2,
INIT_FINDING_SECOND_WALL)
{
asserv_push_the_wall (INIT_SECOND_WALL_PUSH);
- return FSM_NEXT_TIMEOUT (INIT_WAITING_AFTER_FACING_SECOND_WALL);
}
FSM_TRANS (INIT_FINDING_SECOND_WALL, robot_move_success,
INIT_GOING_AWAY_SECOND_WALL)
{
asserv_move_linearly (INIT_SECOND_WALL_AWAY);
- return FSM_NEXT (INIT_FINDING_SECOND_WALL, robot_move_success);
}
#ifdef INIT_START_POSITION_ANGLE
@@ -150,14 +141,12 @@ FSM_TRANS (INIT_GOING_AWAY_SECOND_WALL, robot_move_success,
INIT_FACING_START_POSITION)
{
asserv_goto_angle (INIT_START_POSITION_ANGLE);
- return FSM_NEXT (INIT_GOING_AWAY_SECOND_WALL, robot_move_success);
}
FSM_TRANS (INIT_FACING_START_POSITION, robot_move_success,
INIT_GOING_TO_START_POSITION)
{
asserv_goto_xya (INIT_START_POSITION);
- return FSM_NEXT (INIT_FACING_START_POSITION, robot_move_success);
}
#else
@@ -166,7 +155,6 @@ FSM_TRANS (INIT_GOING_AWAY_SECOND_WALL, robot_move_success,
INIT_GOING_TO_START_POSITION)
{
asserv_goto_xya (INIT_START_POSITION);
- return FSM_NEXT (INIT_GOING_AWAY_SECOND_WALL, robot_move_success);
}
#endif
@@ -174,15 +162,13 @@ FSM_TRANS (INIT_GOING_AWAY_SECOND_WALL, robot_move_success,
FSM_TRANS (INIT_GOING_TO_START_POSITION, robot_move_success,
INIT_WAITING_SECOND_JACK_OUT)
{
- fsm_queue_post_event (FSM_EVENT (AI, init_done));
+ fsm_queue_post_event (FSM_EVENT (init_done));
asserv_set_speed (BOT_SPEED_NORMAL);
- return FSM_NEXT (INIT_GOING_TO_START_POSITION, robot_move_success);
}
FSM_TRANS (INIT_WAITING_SECOND_JACK_OUT, jack_removed, INIT_FINISHED)
{
chrono_start ();
- fsm_queue_post_event (FSM_EVENT (AI, init_start_round));
- return FSM_NEXT (INIT_WAITING_SECOND_JACK_OUT, jack_removed);
+ fsm_queue_post_event (FSM_EVENT (init_start_round));
}