基于配置表(转移表 / 状态表)的通用状态机框架


一、状态和事件枚举

 1typedef enum {
 2    STATE_IDLE,
 3    STATE_PROCESSING,
 4    STATE_ACTION,
 5    STATE_ERROR,
 6    STATE_MAX
 7} fsm_state_t;
 8
 9typedef enum {
10    EVENT_NONE,
11    EVENT_START,
12    EVENT_DONE,
13    EVENT_FAIL,
14    EVENT_MAX
15} fsm_event_t;

二、动作函数类型

1typedef void (*fsm_action_t)(void);

示例动作函数:

1void action_init(void) { /* 初始化逻辑 */ }
2void action_process(void) { /* 核心处理逻辑 */ }
3void action_post(void) { /* 执行动作 */ }
4void action_error(void) { /* 错误处理 */ }

三、状态机表定义

1typedef struct {
2    fsm_state_t current_state; // 当前状态
3    fsm_event_t event;         // 触发事件
4    fsm_action_t action;       // 执行动作
5    fsm_state_t next_state;    // 下一个状态
6} fsm_table_entry_t;

配置表示例:

1fsm_table_entry_t fsm_table[] = {
2    {STATE_IDLE,       EVENT_START, action_init,     STATE_PROCESSING},
3    {STATE_PROCESSING, EVENT_DONE,  action_process,  STATE_ACTION},
4    {STATE_PROCESSING, EVENT_FAIL,  action_error,    STATE_ERROR},
5    {STATE_ACTION,     EVENT_NONE,  action_post,     STATE_IDLE},
6    {STATE_ERROR,      EVENT_NONE,  action_error,    STATE_IDLE}
7};

四、状态机执行函数

 1void fsm_handle_event(fsm_state_t *state, fsm_event_t event) {
 2    for(int i = 0; i < sizeof(fsm_table)/sizeof(fsm_table[0]); i++) {
 3        if(fsm_table[i].current_state == *state && fsm_table[i].event == event) {
 4            if(fsm_table[i].action)
 5                fsm_table[i].action();
 6            *state = fsm_table[i].next_state;
 7            break;
 8        }
 9    }
10}

五、使用示例

1fsm_state_t current_state = STATE_IDLE;
2
3// 触发事件
4fsm_handle_event(&current_state, EVENT_START);  // Idle -> Processing
5fsm_handle_event(&current_state, EVENT_DONE);   // Processing -> Action
6fsm_handle_event(&current_state, EVENT_NONE);   // Action -> Idle

✅ 优点

  1. 可扩展性强:新增状态或事件只需在表里添加一行,无需修改核心代码。
  2. 可维护性高:状态逻辑全部集中在表格中,清晰直观。
  3. 动作自由组合:不同状态+事件可执行不同动作,支持函数指针调用。
  4. 类 DCM 风格:符合 AUTOSAR 状态机/诊断模块逻辑设计。