lib: smf: Fix handled bug causing events to not propagate.
When using the SMF for a project discovered that events would sometimes not propagate to parent states correctly. Could not create a minimum reproducable test case for this, but it was found that these changes fixed the bug. This commit creates a new function to reset internal state, which is called on entry to smf_set_initial() and smf_set_state(). Closes #81300. Signed-off-by: Geoffrey Hunter <gbmhunter@gmail.com>
This commit is contained in:
parent
1e75491cdb
commit
fa795f4912
1 changed files with 23 additions and 10 deletions
|
|
@ -148,8 +148,6 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx)
|
||||||
|
|
||||||
/* The child state either transitioned or handled it. Either way, stop propagating. */
|
/* The child state either transitioned or handled it. Either way, stop propagating. */
|
||||||
if (internal->new_state || internal->handled) {
|
if (internal->new_state || internal->handled) {
|
||||||
internal->new_state = false;
|
|
||||||
internal->handled = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,9 +171,6 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal->new_state = false;
|
|
||||||
internal->handled = false;
|
|
||||||
|
|
||||||
/* All done executing the run actions */
|
/* All done executing the run actions */
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -209,10 +204,24 @@ static bool smf_execute_all_exit_actions(struct smf_ctx *const ctx, const struct
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMF_ANCESTOR_SUPPORT */
|
#endif /* CONFIG_SMF_ANCESTOR_SUPPORT */
|
||||||
|
|
||||||
void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state)
|
/**
|
||||||
|
* @brief Reset the internal state of the state machine back to default values.
|
||||||
|
* Should be called on entry to smf_set_initial() and smf_set_state().
|
||||||
|
*
|
||||||
|
* @param ctx State machine context.
|
||||||
|
*/
|
||||||
|
static void smf_clear_internal_state(struct smf_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct internal_ctx *const internal = (void *)&ctx->internal;
|
struct internal_ctx *const internal = (void *)&ctx->internal;
|
||||||
|
|
||||||
|
internal->is_exit = false;
|
||||||
|
internal->terminate = false;
|
||||||
|
internal->handled = false;
|
||||||
|
internal->new_state = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state)
|
||||||
|
{
|
||||||
#ifdef CONFIG_SMF_INITIAL_TRANSITION
|
#ifdef CONFIG_SMF_INITIAL_TRANSITION
|
||||||
/*
|
/*
|
||||||
* The final target will be the deepest leaf state that
|
* The final target will be the deepest leaf state that
|
||||||
|
|
@ -223,15 +232,14 @@ void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal->is_exit = false;
|
smf_clear_internal_state(ctx);
|
||||||
internal->terminate = false;
|
|
||||||
internal->handled = false;
|
|
||||||
internal->new_state = false;
|
|
||||||
ctx->current = init_state;
|
ctx->current = init_state;
|
||||||
ctx->previous = NULL;
|
ctx->previous = NULL;
|
||||||
ctx->terminate_val = 0;
|
ctx->terminate_val = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_SMF_ANCESTOR_SUPPORT
|
#ifdef CONFIG_SMF_ANCESTOR_SUPPORT
|
||||||
|
struct internal_ctx *const internal = (void *)&ctx->internal;
|
||||||
|
|
||||||
ctx->executing = init_state;
|
ctx->executing = init_state;
|
||||||
const struct smf_state *topmost = get_last_of(init_state);
|
const struct smf_state *topmost = get_last_of(init_state);
|
||||||
|
|
||||||
|
|
@ -389,6 +397,11 @@ int32_t smf_run_state(struct smf_ctx *const ctx)
|
||||||
return ctx->terminate_val;
|
return ctx->terminate_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Executing a states run function could cause a transition, so clear the
|
||||||
|
* internal state to ensure that the transition is handled correctly.
|
||||||
|
*/
|
||||||
|
smf_clear_internal_state(ctx);
|
||||||
|
|
||||||
#ifdef CONFIG_SMF_ANCESTOR_SUPPORT
|
#ifdef CONFIG_SMF_ANCESTOR_SUPPORT
|
||||||
ctx->executing = ctx->current;
|
ctx->executing = ctx->current;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue