Skip to content

Lib: SMF Modify HSM operation for UML-Style transitions #71729

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

Merged
merged 1 commit into from
May 23, 2024

Conversation

glenn-andrews
Copy link
Collaborator

@glenn-andrews glenn-andrews commented Apr 21, 2024

A possible solution to #71675

Modify the SMF such that state transitions from parent states choose the correct Least Common Ancestor based on the transition source rather than the current state.

Also, SMF_CREATE_STATE() now always takes five arguments so all types of state machines (flat and hierarchical with and without initial transitions) can be used in the same project without errors. This is in response to #71252 The only subsystem using SMF, UCB-C, has been updated to take 5 arguments.

@zephyrbot zephyrbot added area: USB Universal Serial Bus area: State Machine Framework State Machine Framework area: USB-C labels Apr 21, 2024
@glenn-andrews glenn-andrews force-pushed the smf_uml_rules branch 4 times, most recently from 1f035e2 to 5416d51 Compare April 21, 2024 17:01
@zephyrbot zephyrbot added the Release Notes To be mentioned in the release notes label Apr 21, 2024
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually an entirely new file, not a rename.

lib/smf/smf.c Outdated
};

static bool share_paren(const struct smf_state *test_state,
const struct smf_state *target_state)
#if CONFIG_SMF_ANCESTOR_SUPPORT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you're using the __unused attribute, wrapping these functions in an #ifdef isn't required.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #ifdef is required because we conditionally compile in parent in smf_state

Should I delete the __unused?

Copy link
Collaborator

@keith-zephyr keith-zephyr May 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.
Sorry - I responded before looking at the latest patchset. You need either __unused or #ifdef. I'm good with the __unused.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, Done.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Sorry - I responded before looking at the latest patchset. You need either __unused or #ifdef. I'm good with the __unused.

Unfortunately you need the #ifdefs, so I'll delete the __unused

@glenn-andrews
Copy link
Collaborator Author

Review comments fixed or otherwise addressed.

@keith-zephyr Please can you take another look?

@glenn-andrews glenn-andrews force-pushed the smf_uml_rules branch 2 times, most recently from a48b474 to 1460d7d Compare May 20, 2024 15:02
Comment on lines 107 to 108
.. note:: State machines can only call :c:func:`smf_set_state` from Run
functions, not Entry or Exit functions.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this sentence. It is conflict with the previous note.

Suggested change
.. note:: State machines can only call :c:func:`smf_set_state` from Run
functions, not Entry or Exit functions.

lib/smf/smf.c Outdated
static bool share_paren(const struct smf_state *test_state,
const struct smf_state *target_state)
const struct smf_state *target_state)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run clang-format on this?

lib/smf/smf.c Outdated
Comment on lines 340 to 346
/*
* The final target will be the deepest leaf state that
* the target contains. Set that as the real target.
*/
while (new_state->initial) {
new_state = new_state->initial;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the indentation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drat. Thought i caught them all. Clang-format run on the file.

Copy link
Collaborator

@keith-zephyr keith-zephyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting pretty close.
I'm also going to test this against my downstream uses of the SMF.

Comment on lines 161 to 164
if (o->terminate == ROOT_ENTRY) {
smf_set_terminate(obj, -1);
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition never occurs and isn't verified by the test.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking - prefer that you delete since it isn't used.

Suggested change
if (o->terminate == ROOT_ENTRY) {
smf_set_terminate(obj, -1);
return;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to build a test that tests termination in root_entry? I think the other tests have that covered with PARENT_ENTRY not wrapped in a root state.

lib/smf/smf.c Outdated
@@ -35,8 +33,7 @@ static bool share_paren(const struct smf_state *test_state,
return false;
}

static bool last_state_share_paren(struct smf_ctx *const ctx,
const struct smf_state *state)
static bool last_state_share_paren(struct smf_ctx *const ctx, const struct smf_state *state)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function no longer has any callers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it's killing the tests. Let me delete it.

@keith-zephyr
Copy link
Collaborator

I tested this change against our downstream uses. Our unit tests pass and the code boots.

Downstream uses:
Power Delivery Subsystem
Power Delivery Driver

@glenn-andrews
Copy link
Collaborator Author

glenn-andrews commented May 20, 2024 via email

keith-zephyr
keith-zephyr previously approved these changes May 20, 2024
Comment on lines 161 to 164
if (o->terminate == ROOT_ENTRY) {
smf_set_terminate(obj, -1);
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking - prefer that you delete since it isn't used.

Suggested change
if (o->terminate == ROOT_ENTRY) {
smf_set_terminate(obj, -1);
return;
}

Modify the SMF such that state transitions from parent states choose the
correct Least Common Ancestor based on the transition source rather than
the current state.

SMF set as experimental.

Signed-off-by: Glenn Andrews <[email protected]>
@glenn-andrews
Copy link
Collaborator Author

@sambhurst Do you have time to look at this?

Copy link
Collaborator

@sambhurst sambhurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@nashif nashif merged commit 531c457 into zephyrproject-rtos:main May 23, 2024
24 checks passed
@henrikbrixandersen
Copy link
Member

@glenn-andrews In the future, please avoid mixing whitespace changes with functional changes in the same commit. It makes it very difficult to isolate and review (and understand) the actual, functional changes. Thanks!

@glenn-andrews
Copy link
Collaborator Author

@glenn-andrews In the future, please avoid mixing whitespace changes with functional changes in the same commit. It makes it very difficult to isolate and review (and understand) the actual, functional changes. Thanks!

Very good point and I will attempt to do so.

That leads me to a question, though.

I tried using Format Selection in VSCode on places I touched, which works, but doing so manually means I may miss some (as I did above with indentation) I then ran clang-format on the entire file as requested, which would change formatting for the entire file.

If the file does not currently comply with clang-format, what is the appropriate procedure?

May I run clang-format in one commit, then make code changes in a second commit in the same PR, or do they have to be separate PRs?

@henrikbrixandersen
Copy link
Member

I tried using Format Selection in VSCode on places I touched, which works, but doing so manually means I may miss some (as I did above with indentation) I then ran clang-format on the entire file as requested, which would change formatting for the entire file.

If the file does not currently comply with clang-format, what is the appropriate procedure?

May I run clang-format in one commit, then make code changes in a second commit in the same PR, or do they have to be separate PRs?

If you really feel the need to reformat an entire file like this, please do so in a separate commit. It is okay to include it in the same PR as a set of functional changes.

@glenn-andrews
Copy link
Collaborator Author

If you really feel the need to reformat an entire file like this, please do so in a separate commit. It is okay to include it in the same PR as a set of functional changes.

Thank you. I'll try to do so in future. It's not so much feeling the need to touch the entire file as making sure my part is formatted correctly, which is easier if I can just clang-format the document before committing rather than only formatting the parts I touched.

Maybe I should run clang-format on the entire source tree and submit that as a PR 😉

@henrikbrixandersen
Copy link
Member

Maybe I should run clang-format on the entire source tree and submit that as a PR 😉

You wouldn't be the first ;)

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 area: USB Universal Serial Bus area: USB-C Release Notes To be mentioned in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants