3. 系统架构设计:硬件系统框图设计、软件分层架构、通信协议栈概览
好,咱们进入第三章。这一章我把它叫做「骨架搭建」。
你想想看,一个多协议照明网关,说白了就是要把 Zigbee、BLE、Wi-Fi、Thread 这些乱七八糟的无线协议,统统塞进一个盒子里,还得让它们互不打架。嗯,这活儿我干过好几次,第一次搞的时候差点翻车。所以这一章,我把我的经验拆开给你看。
3.1 硬件系统框图设计
我个人习惯,画框图之前先列需求。照明网关要接多少灯?50个?200个?要不要本地场景联动?要不要 OTA?这些决定了主芯片选型。
我常用的一个典型架构是这样的:
+------------------+ +------------------+
| Wi-Fi/BT SoC |<--->| Zigbee/Thread |
| (ESP32-S3) | | (EFR32MG24) |
+--------+---------+ +--------+---------+
| |
| UART / SPI | UART / SPI
| |
v v
+------------------+ +------------------+
| PMIC & Power | | RF Front-End |
| (TPS65233) | | (SKY66112) |
+------------------+ +------------------+
|
v
+------------------+
| External Flash |
| (16MB NOR) |
+------------------+
这里我解释一下为什么这么搭。
- 主控 SoC:我选 ESP32-S3,因为它 Wi-Fi 和 BLE 双模,生态好,而且我踩过坑——早期用 ESP8266 做网关,内存不够,跑 MQTT 都卡。S3 的 512KB SRAM 基本够用。
- 协处理器:EFR32MG24 专门跑 Zigbee 和 Thread。为什么分开?因为 Wi-Fi 和 Zigbee 共用 2.4GHz 频段,如果放在一个芯片里,干扰问题会让你想砸板子。我经历过一次,Zigbee 网络动不动掉线,最后发现是 Wi-Fi 发包时把 Zigbee 的时隙冲了。
- 电源管理:照明网关通常 24V 供电,内部要转 3.3V 和 1.8V。我建议用 TPS65233,它带使能时序,能保证 RF 部分先上电,避免启动时射频乱发。
关键设计要点:
- RF 走线必须 50 欧姆阻抗匹配,我吃过亏——第一次打板回来,Zigbee 灵敏度只有 -85dBm,查了半天发现是天线匹配网络焊错了电容。
- 晶振要靠近芯片,走线越短越好。32.768kHz 的 RTC 晶振尤其敏感,旁边不要走数字信号。
- 预留 SWD/JTAG 调试接口,别问我为什么——有一次量产固件出了问题,没有调试口,只能拆芯片下来烧录,那叫一个酸爽。
3.2 软件分层架构
软件架构这块,我建议你参考「嵌入式物联网分层模型」。说白了,就是让每一层只管自己的事,别越界。
我常用的分层是这样的:
| 层级 | 职责 | 示例组件 |
|---|---|---|
| 应用层 | 业务逻辑、场景联动、用户接口 | 灯控逻辑、定时任务、MQTT 客户端 |
| 中间件层 | 协议转换、数据缓存、OTA 管理 | 协议适配器、环形缓冲区、OTA 服务 |
| 驱动层 | 硬件抽象、外设控制、RF 配置 | SPI 驱动、UART 驱动、GPIO 控制 |
| 硬件层 | 物理芯片、射频前端、电源 | ESP32-S3、EFR32MG24、SKY66112 |
你可能会问:「为什么中间件层要单独拎出来?」
嗯,这个问题我当年也困惑过。后来在一个项目里,客户要求同时支持 Zigbee 3.0 和 Matter 协议。如果没有中间件层,你就要在应用层里写一堆 if-else 判断协议类型,代码会变得跟意大利面一样乱。有了中间件层,协议适配器统一接口,应用层根本不用管底层是 Zigbee 还是 Thread。
我的小技巧:
中间件层里一定要放一个「消息队列」。我曾经在一个项目里,Zigbee 上报数据和 Wi-Fi 下发指令同时发生,导致互斥锁死锁。后来加了环形缓冲区的消息队列,问题就解决了。说白了,就是让数据排队,别抢资源。
3.3 通信协议栈概览
这一节可能是你最头疼的。多协议网关,协议栈怎么选?怎么共存?
我直接给你看一个实际项目中的协议栈配置:
+---------------------------------------------------+
| 应用层协议 |
| MQTT (Wi-Fi) | Zigbee ZCL | BLE GATT |
+---------------------------------------------------+
| 传输层 |
| TCP/UDP (Wi-Fi) | Zigbee NWK | BLE L2CAP |
+---------------------------------------------------+
| 网络层 |
| IPv4/IPv6 (Wi-Fi) | Zigbee 6LoWPAN | BLE HCI |
+---------------------------------------------------+
| MAC/PHY 层 |
| Wi-Fi 802.11 b/g/n | Zigbee 802.15.4 | BLE |
+---------------------------------------------------+
这里有几个坑,我帮你提前踩了:
- Wi-Fi 和 Zigbee 共存:它们都在 2.4GHz,同时收发会互相干扰。我建议用「时分复用」——Wi-Fi 发包时,Zigbee 暂时休眠。ESP32-S3 有个 Coexistence 硬件机制,可以自动协调。但注意,这个机制需要你在初始化时配置好优先级。
- Zigbee 协议栈选型:如果你用 EFR32,Silicon Labs 的 EmberZNet 是首选。但如果你用 NXP 的 JN5169,那就要用他们自家的 SDK。我个人更推荐 EFR32,因为它的调试工具 Simplicity Studio 真的很好用,抓包分析一目了然。
- BLE 的 Mesh 支持:照明场景里,BLE Mesh 越来越流行。但注意,BLE Mesh 的延迟比 Zigbee 大,不适合实时性要求高的场景。我做过测试,Zigbee 组播延迟约 20ms,BLE Mesh 约 100ms。所以如果你要做舞台灯光同步,还是老老实实用 Zigbee。
警告:
千万不要在同一个芯片上同时跑 Wi-Fi 和 Zigbee 的全功能协议栈!我见过有人用 ESP32 同时跑 ESP-Zigbee-SDK 和 Wi-Fi,结果内存爆了,系统频繁重启。正确的做法是:Wi-Fi 主控 + 协处理器跑 Zigbee,两者通过 UART 通信。
最后,关于协议栈的初始化顺序,我建议这样:
- 先初始化电源和时钟
- 再初始化 Wi-Fi 协议栈(因为它需要联网获取时间)
- 然后初始化 Zigbee 协议栈(它需要从 Wi-Fi 获取网络参数)
- 最后启动 BLE 广播(用于配网)
这个顺序我踩过坑——有一次我先启动了 Zigbee,结果 Wi-Fi 还没连上,Zigbee 网络无法获取时间戳,导致场景联动的时间轴全乱了。
好了,这一章就到这里。下一章我们开始动手画原理图,到时候我会把每个引脚的连接细节都讲清楚。
本章小结:
- 硬件框图:主控 + 协处理器 + 独立 RF 前端
- 软件分层:应用层、中间件层、驱动层、硬件层
- 协议栈共存:时分复用 + 硬件 Coexistence 机制
公众号:蓝海资料掘金营,微信deep3321