一个轻量级、可移植、支持层级状态的 C 语言状态机框架,适用于嵌入式和Linux应用
1. 介绍
一个轻量级、可移植、支持层级状态的 C 语言状态机框架,适用于嵌入式和Linux应用。
本框架采用数据驱动方式,支持父子状态、入口/出口动作、守卫条件、外部/内部转换、未处理事件钩子等特性。
- 本文修改后的版本:https://gitee.com/liudegui/state_machine
- RT-Thread社区维护的版本:https://gitee.com/RT-Thread-Mirror/state_machine
- state_machine的作者是misje, github地址: https://github.com/misje/stateMachine
2. 相比RT-Thread社区改动点
2.1 过程驱动 → 数据驱动
- 改进前:状态处理分散在各自 handler,需手写 switch-case。
- 改进后:采用转换表(
SM_Transition数组)集中描述事件、目标状态、守卫、动作和类型,SM_Dispatch统一查表处理,开发者无需再写繁琐分支。
2.2 功能增强
- 守卫/动作:转换表支持 guard/action 指针。
- 内外转换区分:支持
SM_TRANSITION_EXTERNAL(完整 exit/entry)和SM_TRANSITION_INTERNAL(仅 action,不变状态)。
2.3 安全与健壮性
- 消除递归:entry 动作改为迭代,避免栈溢出。
- 高效 LCA:最低共同祖先算法优化为 O(N)。
- 用户缓冲区:路径缓冲由用户提供,内存更安全。
- 未处理事件钩子:支持 unhandledEventHook,便于调试。
2.4 代码质量与规范
- MISRA C:重构为单一返回点。
3. 特性
- 支持层级(嵌套)状态
- 支持外部/内部转换
- 支持入口/出口/转换动作
- 支持守卫条件
- 支持未处理事件钩子
- 与操作系统无关,适配 RT-Thread、裸机等
4. 快速开始
4.1. 定义事件
enum
{
EV_POWER_ON,
EV_START_TASK,
EV_TASK_COMPLETE,
EV_POWER_OFF
};
4.2. 定义状态与转换
// 前置声明
static const SM_State STATE_Off, STATE_On, STATE_Idle, STATE_Running;
// 转换表
const SM_Transition T_Off[] = {
{EV_POWER_ON, &STATE_Idle, NULL, NULL, SM_TRANSITION_EXTERNAL}
};
const SM_Transition T_On[] = {
{EV_POWER_OFF, &STATE_Off, NULL, on_power_off, SM_TRANSITION_EXTERNAL}
};
const SM_Transition T_Idle[] = {
{EV_START_TASK, &STATE_Running, can_start_task, NULL, SM_TRANSITION_EXTERNAL}
};
const SM_Transition T_Running[] = {
{EV_TASK_COMPLETE, &STATE_Idle, NULL, on_task_done, SM_TRANSITION_EXTERNAL}
};
// 状态定义
static const SM_State STATE_Off = {
.parent = NULL,
.entryAction = NULL,
.exitAction = NULL,
.transitions = T_Off,
.numTransitions = sizeof(T_Off) / sizeof(T_Off[0]),
.name = "Off"
};
static const SM_State STATE_On = {
.parent = NULL,
.entryAction = entry_On,
.exitAction = exit_On,
.transitions = T_On,
.numTransitions = sizeof(T_On) / sizeof(T_On[0]),
.name = "On"
};
static const SM_State STATE_Idle = {
.parent = &STATE_On,
.entryAction = entry_Idle,
.exitAction = NULL,
.transitions = T_Idle,
.numTransitions = sizeof(T_Idle) / sizeof(T_Idle[0]),
.name = "Idle"
};
static const SM_State STATE_Running = {
.parent = &STATE_On,
.entryAction = entry_Running,
.exitAction = exit_Running,
.transitions = T_Running,
.numTransitions = sizeof(T_Running) / sizeof(T_Running[0]),
.name = "Running"
};
4.3. 定义动作与守卫
void entry_On(SM_StateMachine *sm, const SM_Event *event) { printf(" (Entry)-> On\n"); }
void exit_On(SM_StateMachine *sm, const SM_Event *event) { printf(" (Exit) -> On\n"); }
void entry_Idle(SM_StateMachine *sm, const SM_Event *event) { printf(" (Entry)-> Idle\n"); }
void entry_Running(SM_StateMachine *sm, const SM_Event *event) { printf(" (Entry)-> Running\n"); }
void exit_Running(SM_StateMachine *sm, const SM_Event *event) { printf(" (Exit) -> Running\n"); }
void on_power_off(SM_StateMachine *sm, const SM_Event *event) { printf(" Action: Shutting down...\n"); }
void on_task_done(SM_StateMachine *sm, const SM_Event *event)
{
AppData *data = (AppData *)sm->userData;
data->tasks_completed++;
printf(" Action: Task finished. Total completed: %d\n", data->tasks_completed);
}
bool can_start_task(SM_StateMachine *sm, const SM_Event *event)
{
AppData *data = (AppData *)sm->userData;
printf(" Guard: Checking if tasks completed < 3... (%s)\n", (data->tasks_completed < 3) ? "Yes" : "No");
return data->tasks_completed < 3;
}
4.4. 初始化与事件分发
#define MAX_STATE_DEPTH 8
const SM_State *path_buffer[MAX_STATE_DEPTH];
AppData app_data = {0};
SM_StateMachine sm;
SM_Init(&sm, &STATE_Off, path_buffer, MAX_STATE_DEPTH, &app_data, on_unhandled_event);
SM_Event ev_power_on = {EV_POWER_ON, NULL};
SM_Dispatch(&sm, &ev_power_on);
4.5. 查询状态
printf("Current state: %s\n", SM_GetCurrentStateName(&sm));
printf("Is in state 'On'? %s\n", SM_IsInState(&sm, &STATE_On) ? "Yes" : "No");
4.6. 重置与反初始化
SM_Reset(&sm);
SM_Deinit(&sm);
5. API 说明
详见 state_machine.h 注释。
void SM_Init(...):初始化状态机实例void SM_Deinit(...):反初始化void SM_Reset(...):重置到初始状态bool SM_Dispatch(...):分发事件bool SM_IsInState(...):判断当前状态是否为某状态或其子状态const char* SM_GetCurrentStateName(...):获取当前状态名
6. 示例输出
Initial state: Off
Is in state 'On'? No
(Entry)-> On
(Entry)-> Idle
Current state: Idle
Is in state 'On'? Yes
Is in state 'Idle'? Yes
--- Unhandled Event Hook: Event 99 received in state 'Idle' ---
(Exit) -> On
After reset, current state: Off
After deinit, current state name: Unknown
7. 进阶用法
- 支持父子状态(如
STATE_Idle、STATE_Running的父状态为STATE_On) - 支持守卫条件(guard),可实现条件分支
- 支持未处理事件钩子(unhandledEventHook),便于调试和容错
- 支持用户数据指针(userData),便于携带上下文
8. 适用场景
- 嵌入式设备状态管理
- 协议栈状态机
- 复杂业务流程建模
- 需要层级状态的场合
9. 许可证
MIT License,详见源码头部。
如需更多示例,请参考 examples/ 目录下的代码。
10. Examples
使用示例在 examples 下。

811

被折叠的 条评论
为什么被折叠?



