Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMF smf_set_handled() bug preventing event propagation to parent states. #81300

Open
gbmhunter opened this issue Nov 12, 2024 · 2 comments
Open
Assignees
Labels
area: State Machine Framework State Machine Framework bug The issue is a bug, or the PR is fixing a bug

Comments

@gbmhunter
Copy link

gbmhunter commented Nov 12, 2024

I think there might be a bug in the Zephyr state machine framework (SMF) that causes smf_set_handled() to cause future calls to smf_run_state() to not propagate events up the state hierarchy in HSMs in certain situations.

I am using a state hierarchy in where there is a state S1 which has multiple child states S1A, S1B, e.t.c. S1A calls smf_set_handled() on one event, and then a second event comes it to cause the state machine to transition to other child states like S1B. At some point the state machine transitions back to S1A.

It is here that I've noticed that an event can come in to S1A, and the parent state run() functions are not called. I am definitely not calling smf_set_handled() or smf_set_state() in the s1a_run() function, thus I'm not handling the event and would expect the parent run() functions to be called in backwards order.

Unfortunately the code that causes bug is private and I cannot share it. I tried to recreate a minimal working example but haven't yet been able to trigger the bug (my attempt is here: https://github.com/gbmhunter/zephyr-examples/tree/main/apps/state-machine-framework).

Further evidence that has me thinking this is a bug with the SMF library is that if I modify zephyr/lib/smf/smf.c so that handled is set to false everytime smf_run_state() is called, the bug goes away. To me, this seems like a reasonable thing to do, you would expect the handled state to be refreshed to false on every invocation of smf_run_state().

int32_t smf_run_state(struct smf_ctx *const ctx)
{
	struct internal_ctx *const internal = (void *)&ctx->internal;
	internal->handled = false; // Added this line!!!!!!!!!!!!

	/* No need to continue if terminate was set */
	if (internal->terminate) {
		return ctx->terminate_val;
	}

I am running Zephyr v3.7.0, the Zephyr SDK v0.17.0 and building for native_sim. Running this on WSL (Ubuntu).

@gbmhunter gbmhunter added the bug The issue is a bug, or the PR is fixing a bug label Nov 12, 2024
Copy link

Hi @gbmhunter! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

@gbmhunter
Copy link
Author

Update: I've found that the bug can still occur, and had to add internal->new_state = NULL; to the start of smf_run_state() also. Now it is:

int32_t smf_run_state(struct smf_ctx *const ctx)
{
	struct internal_ctx *const internal = (void *)&ctx->internal;
	internal->handled = false; // Added this
 	internal->new_state = NULL; // Added this

	/* No need to continue if terminate was set */
	if (internal->terminate) {
		return ctx->terminate_val;
	}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: State Machine Framework State Machine Framework bug The issue is a bug, or the PR is fixing a bug
Projects
None yet
Development

No branches or pull requests

3 participants