1. 嵌入式系统架构概述
各位同学,咱们今天聊聊嵌入式系统架构。说实话,这词儿听起来挺唬人,但说白了,它就是一套组织代码的规矩。
我做了十几年嵌入式开发,见过太多项目因为一开始没想清楚架构,后期改得痛不欲生。嗯,咱们今天就把这事儿掰扯清楚。
1.1 什么是嵌入式系统架构
嵌入式系统架构,就是你把软件拆成哪些模块,模块之间怎么打招呼,数据怎么流转。
打个比方,你要盖一栋楼。架构就是这栋楼的承重墙、水电管道、房间布局。没有它,你也能把砖垒起来,但垒到三层可能就塌了。
我个人习惯把架构理解成三件事:
- 模块划分:哪些功能放一起,哪些必须分开
- 接口定义:模块之间怎么传数据、怎么触发动作
- 层次关系:谁依赖谁,谁不能依赖谁
举个例子,一个简单的温控器:
// 不好的架构:所有代码揉在一起
void main() {
while(1) {
temp = read_sensor(); // 读传感器
if(temp > 30) { // 业务逻辑
turn_on_fan();
}
delay(1000);
send_to_uart(temp); // 通信
}
}
// 好的架构:分层清晰
void main() {
sensor_init();
comm_init();
while(1) {
temp = sensor_read(); // 驱动层
cmd = temp_control(temp); // 业务层
comm_send(cmd); // 通信层
os_delay(1000); // 系统层
}
}
核心观点:架构不是写出来的,是设计出来的。好的架构让代码像乐高积木,坏的架构让代码像一团乱麻。
1.2 为什么需要架构设计
你可能觉得,小项目要什么架构?直接开干不就完了?
我曾经也这么想。直到有一次,我接手一个智能家居项目,代码量大概5万行。前任工程师把所有逻辑都写在main.c里,一个函数3000行。改一个bug要花三天,因为根本不知道改这里会不会炸了那里。
那次之后,我彻底明白了架构设计的价值:
| 维度 | 没有架构 | 有架构 |
|---|---|---|
| 可维护性 | 改一处,崩一片 | 改模块内部,不影响外部 |
| 可测试性 | 必须上硬件才能测 | 可以单独mock测试 |
| 可移植性 | 换芯片,重写全部 | 只换驱动层,业务层不动 |
| 团队协作 | 一个人改文件,其他人等着 | 各改各的模块,接口对齐就行 |
| 可复用性 | 每个项目从零开始 | 通用模块直接拿来用 |
你想想看,如果你的代码能像搭积木一样,换一个积木不影响其他积木,那该多爽?
避坑指南:我曾经见过一个团队,为了"快速出活",前三个月完全不考虑架构。结果到了第六个月,一个简单的功能迭代需要两周。嗯,后来他们花了两个月重构,比一开始就设计架构多花了三倍时间。
1.3 常见架构模式
嵌入式领域常用的架构模式,我挑三个最典型的讲讲。
1.3.1 分层架构
这是最经典的模式,也是我个人最常用的。说白了,就是把软件按职责分成几层,上层依赖下层,下层不依赖上层。
典型的嵌入式分层:
+-------------------+
| 应用层 | <- 业务逻辑,比如温控策略
+-------------------+
| 中间件层 | <- 协议栈、文件系统、RTOS
+-------------------+
| 硬件抽象层 | <- HAL,屏蔽硬件差异
+-------------------+
| 驱动层 | <- 直接操作寄存器
+-------------------+
| 硬件 | <- MCU、外设
+-------------------+
好处很明显:换芯片只改驱动层和HAL层,应用层代码纹丝不动。我在一个项目中,把STM32换成GD32,只改了驱动层,应用层一行代码没动。
注意:分层架构最大的坑是"跨层调用"。有些人图方便,应用层直接调驱动层。短期看省事,长期看就是给自己埋雷。记住:层与层之间只能通过接口通信,不能越级。
1.3.2 事件驱动架构
这种模式适合响应式系统,比如按键、传感器中断、网络消息等。
核心思想:系统不主动轮询,而是等待事件发生,然后触发对应的处理函数。
// 事件驱动架构示例
typedef enum {
EVT_BUTTON_PRESS,
EVT_SENSOR_READY,
EVT_TIMER_EXPIRED,
EVT_UART_RX
} event_id_t;
typedef struct {
event_id_t id;
uint32_t data;
} event_t;
void event_handler(event_t *evt) {
switch(evt->id) {
case EVT_BUTTON_PRESS:
handle_button(evt->data);
break;
case EVT_SENSOR_READY:
handle_sensor(evt->data);
break;
// ...
}
}
这种架构的好处是低耦合、高响应。坏处是事件多了,调试起来有点头疼。我曾经在一个项目中,事件种类超过50种,事件追踪成了噩梦。后来加了个事件日志模块,才把问题搞定。
1.3.3 微服务架构
你可能觉得微服务是后端的事。其实嵌入式也能用,尤其是复杂的物联网网关、边缘计算设备。
每个功能模块独立运行,通过消息队列或RPC通信。比如:
- 传感器服务:负责采集数据
- 控制服务:负责执行控制逻辑
- 通信服务:负责网络收发
- 日志服务:负责记录运行状态
每个服务可以独立开发、独立测试、独立升级。一个服务挂了,不影响其他服务。
但要注意,微服务在嵌入式上有代价:需要RTOS支持,内存开销大,通信延迟增加。所以一般只在资源丰富的平台上用,比如Cortex-A系列。
| 架构模式 | 适用场景 | 资源需求 | 复杂度 |
|---|---|---|---|
| 分层架构 | 大多数嵌入式系统 | 低 | 低 |
| 事件驱动 | 响应式系统、UI、传感器网络 | 中 | 中 |
| 微服务 | 复杂网关、边缘计算、多核系统 | 高 | 高 |
我的建议:新手从分层架构入手,别一上来就搞微服务。先把分层玩明白了,再考虑其他模式。记住,架构是为业务服务的,不是为了炫技。
1.4 本章知识体系
下面这张图,把咱们这章的核心内容串起来了。你可以把它当成一个思维导图,方便以后复习。
这张图把咱们这章的核心内容串起来了。你可以把它当成一个思维导图,方便以后复习。