dzerik/zs3l-ncp-flash-over-network

GitHub: dzerik/zs3l-ncp-flash-over-network

通过 WiFi 远程将封闭的涂鸦 ZS3L Zigbee 网关刷写为开源 Zigbee 协调器,无需 SWD 或焊接。

Stars: 0 | Forks: 0

# 通过网络刷写 ZS3L Zigbee NCP —— 无需 SWD,无需焊接 将一个 **WBRG1 + ZS3L** Tuya Zigbee 网关——一款以智能家居品牌名义销售的封闭固件集线器——变成 Home Assistant 的开源 **Zigbee coordinator**——完全通过 WiFi 刷写 Silicon Labs **EFR32MG21 (Tuya ZS3L)** NCP,经由网关 Realtek **RTL8721CSM (WBRG1)** 模块上的 OpenBeken 桥接进行。不需要 J-Link,不需要 SWD,也不需要焊接 Zigbee 芯片。 ## 原理 Zigbee 芯片 (EFR32) 无法直接访问——它连接在 RTL8721 的 UART 上。一旦 RTL8721 运行了带有 `uarttcp` 桥接的 [OpenBeken](https://github.com/openshwprojects/OpenBK7231T_App),你就可以通过 TCP 访问 EFR32。但是,正在运行的 NCP 应用无法被指示跳转到其 bootloader,而且 TCP socket 上也没有 DTR/RTS。 原厂网关固件通过驱动两个 RTL8721 GPIO 来更新 NCP:一个 **boot-select strap** 和 **EFR32 reset** 线。我们完全复现了这一操作,只是改为从 OpenBeken 通过 WiFi 进行:将 strap 保持为 HIGH,向 EFR32 reset 发送脉冲,芯片就会进入其 **Gecko bootloader**。然后我们使用一个内置的微型 **XMODEM-CRC** 发送器 (`flasher/flash_zs3l.py`) 上传 `.gbl` 固件。 有两个耗费了数小时的坑(已记录在 [docs/investigation.md](docs/investigation.md) 中): - **硬件流控制。** NCP 构建版本是启用了*硬件流控制*的镜像,因此**除非 OpenBeken 桥接开启了流控制** (`startDriver uarttcp 115200 512 1 1`),否则正在运行的应用程序将**毫无反应**。bootloader 本身不使用流控制,因此刷写工具会将桥接切换为 `flow=0` 以进行刷写,并在运行时切换回 `flow=1`。 - **reset 引脚与其他指南所述不同。** 在此设备上它是 **PB13** (OpenBeken 引脚索引 **45**),而不是 PA28。请使用 `scan-reset` 来查找你设备的对应引脚。 ## 引脚映射(我测试的网关——请自行验证) OpenBeken 平铺引脚索引 = `port*32 + pin` (PA0..31 = 0..31, PB0..31 = 32..63)。 | 信号 | RTL8721 引脚 | OpenBeken 索引 | 驱动方式 | |---|---|---|---| | Zigbee boot-select strap | PB4 | **36** | HIGH 以进入 bootloader | | EFR32 reset (`nRESET`) | PB13 | **45** | 低电平有效脉冲 (active-LOW pulse) | | UART0 桥接 (请勿改动) | PA16/17/18/19 | 16/17/18/19 | RTS0/CTS0/TX0/RX0 | ## 前置条件 1. WBRG1 已经刷入 **OpenBeken** (`OpenRTL8720D`),可在你的局域网内访问,并且桥接正在运行:`startDriver uarttcp 115200 512 1 1`。 2. 一个 ZS3L NCP 固件 `.gbl`。可用的固件位于 [`config/zs3l_zigbee_ncp_8.2.2.0_115200.gbl`](config/) (EmberZNet 8.2.2.0,使用 [`silabs-firmware-builder`](https://github.com/NabuCasa/silabs-firmware-builder) 构建——如果你自行构建,请参阅 [Dockerfile 说明](config/Dockerfile-libdbus.md))。 3. Python 3,以及用于验证的 [`bellows`](https://github.com/zigpy/bellows) (请在 **Python 3.12** 下安装——CLI 在 3.14 上会出错)。 ## 开始刷写 ``` # (可选) 在你的 gateway 上找到 reset pin python3 flasher/flash_zs3l.py --host 192.168.1.68 scan-reset # 强制 bootloader + 上传 firmware python3 flasher/flash_zs3l.py --host 192.168.1.68 \ flash --gbl config/zs3l_zigbee_ncp_8.2.2.0_115200.gbl # 断电重启整个 hub(软件重启不会重置 EFR32!) # 验证(需要在 Python 3.12 上安装 bellows;bridge 必须处于 flow=1) bellows -d socket://192.168.1.68:8888 info # -> EmberZNet version: 8.2.2.0 build 436 ; EmberNodeType.COORDINATOR ``` ## 在 Home Assistant 中使用它 将其作为**辅助 coordinator** 与你现有的设置一起运行。 **ZHA(最简单——HA 内置):** 设置 → 设备与服务 → 添加集成 → *Zigbee Home Automation* → 手动输入 → radio 类型 **EZSP** → 设备路径 `socket://192.168.1.68:8888`。 **Zigbee2MQTT(独立实例):** ``` serial: port: tcp://192.168.1.68:8888 adapter: ember baudrate: 115200 ``` 流控制由 OpenBeken 桥接处理 (`flow=1`);对于 TCP 端口,HA 端不需要任何额外配置。 ## 文件 - `flasher/flash_zs3l.py` —— bootloader 强制进入 + XMODEM 刷写工具 (`enter` / `scan-reset` / `flash` / `run`)。 - `flasher/verify.sh` —— 基于 bellows 的验证脚本。 - `config/` —— 一个可用的 `.gbl`,OpenBeken `autoexec.bat` 变体,以及 Dockerfile 修复。 - `docs/investigation.md` —— 记录了研究过程及走过的死胡同。 - `CREDITS.md` —— 本项目是建立在大量社区工作的基础之上的。 ## 许可证 MIT —— 详见 [LICENSE](LICENSE)。固件 `.gbl` 是通过社区的 `silabs-firmware-builder` 从 Silicon Labs 的 SDK 构建的;其许可遵循 Silicon Labs 的条款。
标签:Home Assistant, OpenBeken, Zigbee, 固件刷写, 智能家居, 物联网, 请求拦截, 逆向工具