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 通信。

最后,关于协议栈的初始化顺序,我建议这样:

  1. 先初始化电源和时钟
  2. 再初始化 Wi-Fi 协议栈(因为它需要联网获取时间)
  3. 然后初始化 Zigbee 协议栈(它需要从 Wi-Fi 获取网络参数)
  4. 最后启动 BLE 广播(用于配网)

这个顺序我踩过坑——有一次我先启动了 Zigbee,结果 Wi-Fi 还没连上,Zigbee 网络无法获取时间戳,导致场景联动的时间轴全乱了。

好了,这一章就到这里。下一章我们开始动手画原理图,到时候我会把每个引脚的连接细节都讲清楚。

本章小结

  • 硬件框图:主控 + 协处理器 + 独立 RF 前端
  • 软件分层:应用层、中间件层、驱动层、硬件层
  • 协议栈共存:时分复用 + 硬件 Coexistence 机制

公众号:蓝海资料掘金营,微信deep3321