3. 多协议并发软件架构

要在同一颗无线 SoC 上让 Zigbee、BLE、Sub-GHz 私有协议甚至 Matter 同时运行,关键不在于“把两套协议代码都编译进去”,而在于理解 Silicon Labs 提供的三层软件架构:Gecko SDK 与 Simplicity Studio 构成开发与组件层,RAIL 与各协议栈构成无线能力层,多协议调度器(Multiprotocol Scheduler)构成时间与射频资源的仲裁层。这三层各司其职,任何一层配置错误都会表现为“单协议正常、并发即丢包”的典型故障。

一、Gecko SDK 与 Simplicity Studio:组件化工程的组织方式

Gecko SDK(GSDK)不是一个大而全的库,而是一组以 .slcc 组件描述文件组织的可裁剪模块。Simplicity Studio 5 通过 Project Configurator 读取这些组件,把用户勾选的功能展开成 autogen 目录下的初始化代码。理解这一点很重要:你在图形界面里勾选的每一项,最终都会变成 sl_ 开头的初始化调用和一组 #define 配置宏。

一个典型的多协议工程会同时引入以下组件:

  • RAIL Library:射频抽象层,提供 RAIL_Init、RAIL_StartTx、RAIL_ConfigEvents 等 API;
  • Bluetooth LE Stack:BLE 协议栈,依赖 RAIL 完成底层收发;
  • Zigbee Stack (EmberZNet):Zigbee 协议栈,同样构建在 RAIL 之上;
  • Multiprotocol Scheduler:调度器组件,负责在多个协议栈之间分配射频时间;
  • Micrium OS / FreeRTOS:RTOS 组件,为调度器提供时基与任务上下文。

组件之间存在依赖关系,Project Configurator 会自动解析。例如勾选 Multiprotocol Scheduler 后,它会强制要求至少两个协议栈组件,并自动引入 RAIL 的 rail_mp_scheduler 支持。若手动修改 .slcp 文件绕过依赖检查,编译期可能通过,但运行期调度器无法注册协议栈,表现为 sl_mp_scheduler_init 返回错误。

二、RAIL 与无线协议栈的分层关系

RAIL(Radio Abstraction Interface Layer)是 Silicon Labs 无线软件栈的“硬件抽象层”,但它比一般 HAL 更靠近射频:它直接管理信道、发射功率、前导码、同步字、CRC、FIFO 和中断。协议栈不直接操作寄存器,而是通过 RAIL 的 API 完成收发。这种分层带来两个直接后果:

  1. 协议栈可以共享同一套射频配置。BLE 使用 2.4 GHz、1 Mbps、GFSK;Zigbee 使用 2.4 GHz、250 kbps、OQPSK。两者物理层参数不同,但都通过 RAIL 的 RAIL_ConfigChannels 和 RAIL_ConfigRadio 切换。
  2. 射频事件必须被仲裁。当 BLE 正在广播、Zigbee 同时要发送信标时,谁先占用射频?这正是调度器要解决的问题。

RAIL 提供的关键机制包括:RAIL_SetTxPower 设置发射功率(例如 0 dBm 或 10 dBm)、RAIL_ConfigEvents 注册 RAIL_EVENT_TX_COMPLETE 等回调、RAIL_HoldRx 与 RAIL_ReleaseRx 实现接收窗口的挂起与恢复。调度器正是利用 RAIL_HoldRx 在协议切换时“冻结”当前接收状态,避免切换过程中丢失正在接收的数据包。

三、多协议调度器原理:时间片与优先级仲裁

Silicon Labs 的多协议调度器采用基于时间片的抢占式仲裁。其核心思想是:每个协议栈向调度器注册自己的“射频需求”,调度器根据优先级和剩余时间片决定当前把射频交给谁。调度器不修改协议栈内部逻辑,只在 RAIL 层之上插入一个仲裁层。

调度器的工作流程可以概括为:

  1. 协议栈调用 sl_mp_scheduler_register_protocol 注册,声明自己的优先级(如 BLE 连接事件优先级高于 Zigbee 信标);
  2. 调度器为每个协议分配时间片,例如 BLE 占 60%、Zigbee 占 40%,时间片以毫秒为单位;
  3. 当某协议需要发送时,调用 sl_mp_scheduler_request_radio 请求射频;
  4. 调度器检查当前时间片归属,若属于请求方则立即授权,否则挂起请求并等待下一个时间片;
  5. 授权后协议栈通过 RAIL 完成收发,完成后调用 sl_mp_scheduler_release_radio 释放。

这里有一个容易忽略的细节:调度器的时间片不是固定轮询,而是“事件驱动 + 优先级抢占”。如果 BLE 连接事件到达而当前 Zigbee 时间片尚未用完,调度器会根据优先级决定是否立即切换。优先级配置错误会导致 BLE 连接事件被 Zigbee 信标阻塞,表现为连接间隔抖动或丢包。

多协议并发软件架构分层与调度关系 应用层 Zigbee 应用任务 | BLE GATT 服务 | Sub-GHz 私有协议任务 Zigbee Stack EmberZNet 信标 / 数据帧 BLE Stack Bluetooth LE 广播 / 连接事件 Sub-GHz Stack 私有协议 长距离 / 低速率 多协议调度器(Multiprotocol Scheduler) 时间片分配 | 优先级仲裁 | 射频请求 / 释放 | HoldRx / ReleaseRx 示例:BLE 60% 时间片,Zigbee 40% 时间片,BLE 连接事件可抢占 RAIL 射频抽象层 信道配置 | 发射功率 | 前导码 / 同步字 | CRC | FIFO | 中断回调 无线 SoC 硬件(EFR32 系列) 协议栈 仲裁层 抽象层

四、实际配置中的关键参数与判断依据

在 Simplicity Studio 中配置多协议工程时,以下几个参数直接决定并发行为:

配置项典型值影响
调度器时间片长度10 ms过短导致切换开销大,过长导致另一协议响应延迟
BLE 优先级高保证连接事件不被 Zigbee 阻塞
Zigbee 优先级中信标和轮询可容忍一定延迟
RAIL 发射功率0 dBm / 10 dBm影响并发时的邻道干扰与功耗
HoldRx 超时100 µs切换协议时接收窗口的保持时间

判断并发是否正常,最直接的方法是观察调度器的统计信息。GSDK 提供 sl_mp_scheduler_get_statistics,可读取每个协议的授权次数、拒绝次数和平均等待时间。若某协议的拒绝次数持续增长,说明时间片分配不足或优先级配置过低。另一个可观察点是 RAIL 的 RAIL_EVENT_RX_PACKET_RECEIVED 回调频率:并发正常时,两个协议的回调应交替出现;若某一协议长时间无回调,说明它被另一协议“饿死”。

调试建议:先用单协议工程确认 RAIL 配置正确,再逐步加入第二个协议栈。每次只增加一个协议,观察调度器统计和丢包率变化。若加入第二个协议后第一个协议丢包率从 0.1% 升至 5% 以上,优先检查时间片比例和优先级,而不是射频参数。

最后需要强调:多协议并发的本质是射频时间的零和博弈。调度器只能优化分配,不能创造时间。因此,在架构设计阶段就应评估各协议的占空比需求。例如 BLE 连接间隔 100 ms、每次连接事件占用 2 ms,则 BLE 占空比约 2%;Zigbee 信标间隔 15.36 ms、每次占用 1 ms,占空比约 6.5%。两者合计不足 10%,调度器有充足余量。但若 BLE 连接间隔缩短到 7.5 ms,占空比升至约 27%,此时必须重新评估时间片分配,否则 Zigbee 响应会明显变慢。