Skip to content

Lib: SMF: Missing execution of ancestor state_run #89950

@Yaxit

Description

@Yaxit

Describe the bug
When using the State Machine Framework (SMF) with ancestor support, the ancestor state's run function is not being executed on the first call to smf_run_state(). However, it correctly executes on subsequent calls. According to SMF documentation, when a state has an ancestor, the ancestor's run function should be called automatically after the child state's run function completes.

To Reproduce
Below is a minimal example to reproduce the issue:

#include <zephyr/smf.h>

/* Forward declaration of state table */
const struct smf_state demo_states[];

/* List of demo states */
enum demo_state { S0, S1};

/* User defined object */
struct s_object {
        /* This must be first */
        struct smf_ctx ctx;

        /* Other state specific data add here */
} s_obj;

int cnt = 0;
/* State S0 */
static void s0_entry(void *o){
        printk("S0 entry\n");
        smf_set_state(SMF_CTX(&s_obj), &demo_states[S1]);
}
static void s0_run(void *o){
        printk("S0 run\n");
        cnt++;
}

static void s0_exit(void *o){
        printk("S0 exit\n");
}

/* State S1 */
static void s1_entry(void *o){
        printk("S1 entry\n");

}
static void s1_run(void *o){
        printk("S1 run. cnt=%d\n", cnt);
}

static void s1_exit(void *o){
        printk("S1 exit\n");
}


/* Populate state table */
const struct smf_state demo_states[] = {
        [S0] = SMF_CREATE_STATE(s0_entry, s0_run, s0_exit, NULL, NULL),
        [S1] = SMF_CREATE_STATE(s1_entry, s1_run, s1_exit, &demo_states[S0], NULL),
};

int main(void)
{
        /* Set initial state */
        smf_set_initial(SMF_CTX(&s_obj), &demo_states[S0]);

        printk("\nIter 1\n");
        smf_run_state(SMF_CTX(&s_obj));
        printk("\nIter 2\n");
        smf_run_state(SMF_CTX(&s_obj));

}

Expected behavior
When using a state with an ancestor, the ancestor's run function should be automatically executed after the child state's run function on every call to smf_run_state().

Expected output:

S0 entry
S1 entry

Iter 1
S1 run. cnt=0
S0 run

Iter 2
S1 run. cnt=1
S0 run

Actual behavior
The ancestor's run function is not executed on the first call to smf_run_state() but works correctly on subsequent calls.

Actual output:

S0 entry
S1 entry

Iter 1
S1 run. cnt=0

Iter 2
S1 run. cnt=0
S0 run

Impact
This issue affects state machine hierarchies that depend on ancestor behavior being consistent across all iterations. It could lead to unexpected behavior in systems relying on ancestor state execution during the first iteration.

Environment:

  • OS: Windows 11
  • Toolchain: Zephyr SDK 0.16.1
  • Zephyr Version: v3.7.99-1f8f3dc29142

Metadata

Metadata

Assignees

Labels

area: State Machine FrameworkState Machine FrameworkbugThe issue is a bug, or the PR is fixing a bugpriority: mediumMedium impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions