嵌入式软件分层架构的设计原理与实践验证(有限状态机理解及结构体封装理解)
文章目录
- 摘要
- 状态机 理解
摘要
是系统架构中专门负责状态管理与状态转换逻辑的抽象层次。它基于有限状态机(Finite State Machine, FSM)的理论模型,用于简化复杂系统的行为控制,尤其在嵌入式系统、通信协议、游戏逻辑等领域广泛应用。
-
状态管理
- 状态(State):代表系统在特定时刻的稳定模式(如“待机”“运行”“错误”)。
- 状态存储:FSM层通过内部变量记录当前状态,作为决策基础。
-
事件响应
- 事件(Event):外部输入或内部条件变化(如按键触发、定时器超时、数据到达)。
- 转换逻辑:事件触发状态转移,FSM层根据预设规则更新状态并执行关联动作。
-
动作执行
- 动作(Action):状态转换时执行的操作(如启动电机、发送数据、更新界面)。
- 支持进入动作(进入状态时执行)、退出动作(离开状态时执行)等细分逻辑。
-
分层设计(HFSM)
复杂系统可能采用分层状态机(Hierarchical FSM),将状态划分为子状态机,例如- 顶层状态:
运行模式
、休眠模式
; - 子状态:
运行模式
下细分采集数据
、处理数据
等。
这种设计减少状态爆炸问题,提升可维护性。
- 顶层状态:
-
硬编码实现
- Switch-Case法:通过
switch(current_state)
分支处理事件,适合简单逻辑。 - 函数指针表:将状态映射到处理函数(如
state_handlers[state]()
),扩展性更优。
- Switch-Case法:通过
-
面向对象实现
- 状态模式(State Pattern):每个状态封装为独立类,通过虚函数统一接口(C++/Java常用)。
FSM层是系统设计中专责状态转换的核心抽象层,通过状态→事件→动作的链式响应,将复杂行为分解为可控单元。它在资源受限的嵌入式环境或高可靠性场景(如航天控制、工业协议)中尤为关键,是平衡复杂性与可维护性的经典解决方案。
状态机 理解
通过 “状态定义→事件响应→动作执行→状态迁移” 的闭环管理
对于状态机需要利用三个状态进行控制。
STATUS_ENTER
、STATUS_RUN
、STATUS_QUIT
:通过结构化生命周期管理解决了复杂系统的行为控制问题。
设计意义:模块化生命周期管理
-
STATUS_ENTER
:承担初始化任务(如外设配置、内存分配、变量复位),确保系统进入稳定起点。
示例:STM32系统上电后初始化GPIO和定时器,加载默认参数。 -
STATUS_RUN
:执行核心业务逻辑(如数据采集、算法处理、实时控制),是系统的“主循环”状态。
示例:电机控制中持续调整PWM输出,维持转速稳定。 -
STATUS_QUIT
:处理终止与清理(如关闭外设、保存状态、释放资源),保障安全退出。
示例:设备关机前保存用户配置到Flash,关闭通信接口。
是将整个系统利用状态机给分离出来。
每个状态对应明确的动作集,事件触发时仅需关注当前状态的行为,而非全局条件分支
STATUS_ENTER 初始化配置:独立出来这样构成一个状态,就能做一些事情(虽然现在可能还用不到,但是接口预留出来了)。
STATUS_RUN 执行业务逻辑层:也就是系统运行
STATUS_QUIT 处理终止与清理:???
STATUS_ENTER → 分配资源 → STATUS_RUN → 释放资源 → STATUS_QUIT
避免资源泄漏(如未关闭的中断、未释放的内存)。
错误隔离与恢复机制
- 异常时可强制跳转至
STATUS_QUIT
,执行统一清理后重新进入STATUS_ENTER
,实现软重启。
分层状态机(HFSM)基础:
若业务复杂,每个状态可进一步拆解为子状态机(如STATUS_RUN
内含采集→处理→发送
子状态)。
- 设备启动流程
ENTER
(初始化时钟/外设) →RUN
(执行控制算法) →QUIT
(停机保存日志)。 - 通信协议处理
ENTER
(建立连接) →RUN
(数据传输) →QUIT
(断开并释放Socket)。 - 用户交互系统
ENTER
(加载界面资源) →RUN
(响应用户输入) →QUIT
(退出动画及资源释放)。
状态 | 核心职责 | 触发条件 | 典型动作 | 转换方向 |
---|---|---|---|---|
**STATUS_ENTER ** | 初始化与准备 | 系统启动/复位 | 资源分配、寄存器配置 | → STATUS_RUN |
**STATUS_RUN ** | 核心业务执行 | 事件驱动(如定时器触发) | 数据处理、控制算法、通信响应 | → 自身或STATUS_QUIT |
**STATUS_QUIT ** | 清理与安全退出 | 关机指令/严重错误 | 资源释放、状态保存、关闭外设 | → 系统停止或重新初始化 |
这三种状态构成了嵌入式系统的最小完备生命周期模型,通过强制划分执行阶段,解决了裸机开发中常见的“初始化与业务逻辑混杂”“异常处理不彻底”等痛点。结合状态表驱动和事件队列(如RTOS消息),可进一步构建高可靠嵌入式框架。
而在状态机下又包含不同的子状态机:如按键状态机、系统状态状态机等
状态(State)
系统在特定时刻的行为模式,例如:
- 按键扫描中的
空闲(IDLE)
、消抖(DEBOUNCE)
、按下(PRESSED)
- 设备运行中的
初始化(INIT)
、运行(RUN)
、故障(FAULT)
特点:状态互斥(同一时刻仅一种状态),且可枚举(有限集合)。
事件(Event)
触发状态转移的外部或内部信号,例如:
- 硬件事件:按键按下、串口数据到达、定时器超时
- 软件事件:数据校验完成、错误标志置位
作用:驱动状态机从“现态”向“次态”迁移。
动作(Action)
状态进入、退出或转移时执行的操作,例如:
- 进入运行状态时启动传感器采样
- 退出故障状态时复位错误计数器
关键:动作与状态绑定,而非嵌入条件分支。
转移(Transition)
事件触发后状态变化的规则。
在嵌入式开发过程中,只要芯片上电就会运行程序,这样通过交互就能实现不同的功能。此时我们就需要定义为上电状态,为什么不是关机状态,这是因为和关机状态处于一个层级的还有自检状态。那么由于存在关机状态和自检状态是一个级别,那么就需要再定义一个状态去管理这两个状态,那上电状态由此产生。所以基于这种思想我们是不是可以理解为在分析状态的时候或者状态跳转的时候我们不是凭空想想的,而是基于一定的逻辑去设置状态,这种逻辑就是产品本身所必须的逻辑,基于产品的功能和逻辑去设计状态才是核心,只有把状态细分以后,然后再去定义具体的功能怎么实现,才是正确的思路。
也就是实现通过 “状态定义→事件响应→动作执行→状态迁移” 的闭环管理。
如果觉得我的内容对您有帮助,希望不要吝啬您的赞和关注,您的赞和关注是我更新优质内容的最大动力。
专栏介绍
《嵌入式通信协议解析专栏》
《PID算法专栏》
《C语言指针专栏》
《单片机嵌入式软件相关知识》
《FreeRTOS源码理解专栏》
《嵌入式软件分层架构的设计原理与实践验证》
文章源码获取方式:
如果您对本文的源码感兴趣,欢迎在评论区留下您的邮箱地址。我会在空闲时间整理相关代码,并通过邮件发送给您。由于个人时间有限,发送可能会有一定延迟,请您耐心等待。同时,建议您在评论时注明具体的需求或问题,以便我更好地为您提供针对性的帮助。
【版权声明】
本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议。这意味着您可以自由地共享(复制、分发)和改编(修改、转换)本文内容,但必须遵守以下条件:
署名:您必须注明原作者(即本文博主)的姓名,并提供指向原文的链接。
相同方式共享:如果您基于本文创作了新的内容,必须使用相同的 CC 4.0 BY-SA 协议进行发布。
感谢您的理解与支持!如果您有任何疑问或需要进一步协助,请随时在评论区留言,笔者一定知无不言,言无不尽。