基于配置表(转移表 / 状态表)的通用状态机框架
一、状态和事件枚举
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(¤t_state, EVENT_START); // Idle -> Processing
5fsm_handle_event(¤t_state, EVENT_DONE); // Processing -> Action
6fsm_handle_event(¤t_state, EVENT_NONE); // Action -> Idle
✅ 优点
- 可扩展性强:新增状态或事件只需在表里添加一行,无需修改核心代码。
- 可维护性高:状态逻辑全部集中在表格中,清晰直观。
- 动作自由组合:不同状态+事件可执行不同动作,支持函数指针调用。
- 类 DCM 风格:符合 AUTOSAR 状态机/诊断模块逻辑设计。
评论