Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dsyx/docs.silabs.com_zh/llms.txt

Use this file to discover all available pages before exploring further.

动态多协议(Dynamic Multiprotocol,DMP)技术允许在单个 EFR32 无线芯片上同时可靠地运行多种无线协议。通过对无线电进行时间分片,并由无线电调度器(Radio Scheduler)智能仲裁,Bluetooth 与 Proprietary RAIL 协议可以共用同一射频硬件,实现设备同时连接 Bluetooth 网络和专有无线网络。本文档基于 GSDK v3.x,详细介绍 Bluetooth/Proprietary DMP 应用的开发方法。

多协议基础概念

无线电调度器

RAIL 中的核心仲裁组件,根据操作的优先级、起始时间、slip time 和事务时间,在协议间智能调度无线电硬件访问

Radio Operation

调度的基本单元,包含无线电配置和优先级。每个协议栈最多可同时请求两个无线电操作:后台接收 + 预定接收/预定传输

Micrium RTOS

DMP 应用的基础运行环境,为每个协议栈提供独立的 RTOS 任务,通过消息队列和信号量实现任务间通信

单一固件映像

DMP 使开发者可以生成单个整体二进制文件加载到 EFR32,通过 Gecko Bootloader 进行整体固件更新

多协议类型对比

类型说明适用场景
编程式(Programmable)芯片在制造时使用一种协议编程灵活的产品线规划
切换式(Switched)通过 bootloader 在协议间切换面向未来的协议升级
动态式(Dynamic)两个协议并发运行,无线电时分复用同时连接 Bluetooth 和专有网络
并发式(Concurrent)共享同一 RF 信道运行两种协议Zigbee/Thread 网关

Bluetooth 与 Proprietary 共存准则

在实现 Bluetooth/Proprietary DMP 之前,需要了解 Bluetooth 的特性约束:
Bluetooth 不会在随机时间收发数据包,而始终在预定义的时间点(连接间隔的起始)收发。这意味着 Bluetooth 不需要后台接收,Proprietary 可以在后台接收,但有时会被中断。
预定义时间点的结果是 Bluetooth 数据包不能被延迟(需要 500 ppm 的时序精度)。如果与 Proprietary 数据包发生冲突,必须延迟 Proprietary 数据包,或丢弃其中一个。
建立连接后,通过每个连接间隔至少收发一个空数据包来保持连接状态。因此 Proprietary 需要准备好在每个连接间隔被中断。可以通过设置较长的连接间隔或从机延迟参数来降低 Bluetooth 通信频率。
一个空数据包在 1M PHY 上发送仅需 80 µs,在 2M PHY 上需 40 µs。完整的空数据包交换(发送 + 帧间间隔 + 接收)需要约 310 µs(1M PHY)或 230 µs(2M PHY)。最大 Bluetooth 数据包(257 byte 负载)交换约需 2350 µs(1M PHY)或 1250 µs(2M PHY)。
如果一个 Bluetooth 数据包无法发送,将在下一个连接间隔重发。较高优先级的无线电任务可以占用 Bluetooth 通信,只要间隔时间短于监督超时(supervision timeout)即可。
设计总结:实施 DMP 时,Bluetooth 会在每个连接间隔(230 µs – 2350 µs 的短时间内)需要无线电。由于时序精确,Bluetooth 数据包不能被延迟。因此 Proprietary 应实现确认和重传机制,或与 Bluetooth 通信交错的确定性时序。

DMP 应用软件架构

DMP 应用基于 Micrium RTOS 运行,各协议在独立的 RTOS 任务中执行:
┌─────────────────────────────────────────────────────┐
│                 DMP 应用程序层                       │
├───────────────────────┬─────────────────────────────┤
│   Bluetooth App Task  │   Proprietary App Task       │
│  (sl_bt_on_event())   │  (proprietaryAppTask())       │
├───────────────────────┼─────────────────────────────┤
│  Bluetooth Host Task  │   RAIL API(直接访问)        │
│  Bluetooth LL Task    │   sl_rail_app_on_event()      │
├───────────────────────┴─────────────────────────────┤
│           RAIL 多协议库(含无线电调度器)              │
├─────────────────────────────────────────────────────┤
│                  EFR32 无线电硬件                    │
└─────────────────────────────────────────────────────┘
  • Bluetooth 通过 BluetoothTask()LinkLayerTask() 运行,通过 BGAPI 访问协议栈功能
  • ProprietaryproprietaryAppTask() 中实现,通过 RAIL API 直接访问无线电
  • RAIL 事件通过 sl_rail_app_on_event() 回调处理(从中断上下文调用)
  • 任务间通信通过 RTOS 的 IPC 机制(信号量、标志组、消息队列)实现

创建 DMP 项目

1

打开 Simplicity Studio 5

启动 SSv5,在 Debug Adapters 视图中选择已连接的设备,或在 My Products 视图中选择目标器件。
2

启动项目向导

点击 File > New > Silicon Labs Project Wizard,在 Target, SDK and Toolchain Selection 对话框中确认使用 Gecko SDK Suite v3.x。如需使用 IAR 请在此处切换(创建后难以更改 toolchain)。点击 NEXT
3

选择 DMP 示例

在 Example Project Selection 对话框中,筛选 Bluetooth,选择 SOC – Empty – RAIL – DMP,点击 NEXT该示例已包含:
  • Multiprotocol RAIL library
  • Bluetooth library
  • Micrium RTOS
  • 默认 Bluetooth GATT database 配置
  • 默认 RAIL 配置
  • RTOS 初始化、Bluetooth 初始化、RAIL 初始化
4

命名并完成

为项目命名,点击 [FINISH]

配置 Bluetooth

  1. 在项目中打开 .slcp 文件
  2. 点击 Software Components 选项卡
  3. 在 Advanced Configurators 下选择 Bluetooth GATT Configurator,点击 Open
  4. 按照 QSG169: Bluetooth® SDK v3.x Quick Start Guide 中的说明添加自定义 services 和 characteristics
  5. 更改将自动保存并生成项目文件

配置 Proprietary 协议

  1. 在项目中打开 .slcp 文件
  2. 点击 Software Components 选项卡
  3. 在 Advanced Configurators 下选择 Radio Configurator,点击 Open
  4. 选择 Base Profile 无线电配置文件
  5. 从列表中选择预定义无线电 PHY,或选择 Custom 手动设置(详情参见 AN1253: EFR32 Radio Configurator Guide for Simplicity Studio 5

让出无线电(Yield)

协议栈必须在一个操作或一系列操作结束时主动让出无线电,否则调度器将不调度更低优先级的任务。
// 多协议场景中,发送完成后必须让出无线电
static void sl_rail_app_on_event(RAIL_Handle_t railHandle, RAIL_Events_t events)
{
    if (events & RAIL_EVENT_TX_PACKET_SENT) {
        RAIL_YieldRadio(railHandle);  // 必须调用!
    }
}
后台接收(RAIL_StartRx())不受 RAIL_YieldRadio() 影响。只有 RAIL_Idle() 才能从后台接收状态中永久移除一个协议。注意 RAIL_Idle() 会清除给定协议的所有事件,不能用于替代 RAIL_YieldRadio()

发送 Proprietary 数据包示例

以下示例演示:每次写入 GATT database 中的特定 characteristic 时,发送一个 Proprietary 数据包。 步骤 1:定义通信标志和 Tx FIFO
// 定义任务间通信标志
#define CHARACTERISTIC_CHANGED ((OS_FLAGS)0x01)

// 在 proprietary_app.c 中定义 Tx FIFO
#define RAIL_TX_FIFO_SIZE (64)
static uint8_t txFifo[RAIL_TX_FIFO_SIZE];
步骤 2:在 Bluetooth 事件处理中设置标志
// 在 sl_bt_on_event() 中处理 characteristic 值变更
case sl_bt_evt_gatt_server_attribute_value_id:
    if (evt->data.evt_gatt_server_attribute_value.attribute == gattdb_prop_char) {
        OSFlagPost(&proprietary_event_flags,
                    CHARACTERISTIC_CHANGED,
                    OS_OPT_POST_FLAG_SET,
                    &err);
    }
    break;
步骤 3:在 Proprietary 任务中发送数据包
// 在 proprietaryAppTask() 无限循环之前,设置 Tx FIFO 和调度器信息
RAIL_SetTxFifo(railHandle, txFifo, 0, RAIL_TX_FIFO_SIZE);
RAIL_SchedulerInfo_t txSchedulerInfo = (RAIL_SchedulerInfo_t){ .priority = 100,
                                                                .slipTime = 100000,
                                                                .transactionTime = 800 };

// 在无限循环内等待标志并发送
while (DEF_TRUE) {
    RTOS_ERR err;
    OSFlagPend(&proprietary_event_flags,
                CHARACTERISTIC_CHANGED,
                (OS_TICK)0,
                OS_OPT_PEND_BLOCKING       \
                + OS_OPT_PEND_FLAG_SET_ANY \
                + OS_OPT_PEND_FLAG_CONSUME,
                NULL,
                &err);
    sl_status_t result;
    result = sl_bt_gatt_server_read_attribute_value(gattdb_prop_char, 0, 16, data_len, dataPacket);
    RAIL_WriteTxFifo(railHandle, dataPacket, data_len, true);
    RAIL_StartTx(railHandle, 0, RAIL_TX_OPTIONS_DEFAULT, &txSchedulerInfo);
}
步骤 4:在 RAIL 事件回调中让出无线电
static void sl_rail_app_on_event(RAIL_Handle_t railHandle, RAIL_Events_t events)
{
    if (events & RAIL_EVENT_TX_PACKET_SENT) {
        RAIL_YieldRadio(railHandle);
    }
}

接收 Proprietary 数据包示例

以下示例为上一节的发送方实现接收方。一旦接收到 Proprietary 数据包,将更新 GATT database 中的 characteristic 并发送 Bluetooth 通知。 步骤 1:定义 Rx 标志和 Rx FIFO
#define PACKET_RECEIVED ((OS_FLAGS)0x02)

#define RAIL_RX_FIFO_SIZE (64)
static uint8_t rxFifo[RAIL_RX_FIFO_SIZE];
步骤 2:在 Proprietary 任务循环前启动接收
// 设置接收后自动返回 Rx 状态的状态转换
RAIL_StateTransitions_t stateTransition = (RAIL_StateTransitions_t){ .success = RAIL_RF_STATE_RX,
                                                                    .error = RAIL_RF_STATE_RX };
RAIL_SetRxTransitions(railHandle, &stateTransition);

// 设置 Rx 优先级(低于 Tx)并启动接收
RAIL_SchedulerInfo_t rxSchedulerInfo = (RAIL_SchedulerInfo_t){ .priority = 200 };
RAIL_StartRx(railHandle, 0, &rxSchedulerInfo);
步骤 3:在 RAIL 事件回调中处理接收事件
if (events & RAIL_EVENT_RX_PACKET_RECEIVED) {
    RAIL_RxPacketInfo_t packetInfo;
    RTOS_ERR err;

    RAIL_GetRxPacketInfo(railHandle,
                        RAIL_RX_PACKET_HANDLE_NEWEST,
                        &packetInfo);

    if (packetInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS) {
        RAIL_CopyRxPacket(rxFifo, &packetInfo);
        OSFlagPost(&proprietary_event_flags, PACKET_RECEIVED, OS_OPT_POST_FLAG_SET, &err);
    }
}
步骤 4:在任务循环中更新 GATT 并发送通知
while (DEF_TRUE) {
    RTOS_ERR err;
    OS_FLAGS active_flags = OSFlagPend(&proprietary_event_flags,
                                        CHARACTERISTIC_CHANGED \
                                        + PACKET_RECEIVED,
                                        (OS_TICK)0,
                                        OS_OPT_PEND_BLOCKING       \
                                        + OS_OPT_PEND_FLAG_SET_ANY \
                                        + OS_OPT_PEND_FLAG_CONSUME,
                                        NULL,
                                        &err);

    if (active_flags & PACKET_RECEIVED) {
        sl_bt_gatt_server_write_attribute_value(gattdb_prop_char, 0, 16, rxFifo);
        sl_bt_external_signal(CHARACTERISTIC_CHANGED);
    }
}
步骤 5:在 Bluetooth 事件处理中发送通知
case sl_bt_evt_system_external_signal_id:
    if (bluetooth_evt->data.evt_system_external_signal.extsignals & CHARACTERISTIC_CHANGED) {
        sl_bt_cmd_gatt_server_send_characteristic_notification(
            0xff, gattdb_prop_char, 16, rxFifo, &sent_len);
    }
    break;

Light/Switch DMP 示例

Light/Switch 示例是 DMP 应用的完整演示:RAIL Switch 应用通过专有 RAIL 协议控制灯的状态,Soc Light Rail Dmp 应用同时运行 Bluetooth 和 RAIL 协议,允许通过 Bluetooth 或专有无线信号控制灯光。

构建 RAIL Switch 应用

1

打开 Simplicity Studio 5

在 Debug Adapters 视图中选择已连接的设备。
2

创建项目

点击 File > New > Silicon Labs Project Wizard,确认 SDK 和 toolchain 后点击 NEXT
3

选择示例

在 Example Project Selection 对话框中筛选 Proprietary,选择 Flex (RAIL) - Switch,点击 NEXT
4

完成创建并烧录

为项目命名,点击 [FINISH]。使用调试按钮自动编译并烧录,或手动编译后加载。应用加载成功后,LCD 会先显示简短菜单,然后切换到灯泡显示。

构建 Bluetooth Light 应用

1

确认 Gecko Bootloader

Bluetooth Light 应用需要设备上预装 Gecko Bootloader。加载预编译的 SOC-Light-Rail-Dmp demo 时会自动包含 bootloader,或参考 UG266: Silicon Labs Gecko Bootloader User’s Guide 手动构建组合映像。
2

创建项目

在 Simplicity Studio 5 中,点击 File > New > Silicon Labs Project Wizard,确认 SDK 和 toolchain 后点击 NEXT
3

选择示例

筛选 Bluetooth,选择 Soc Light Rail Dmp,点击 NEXT,命名后点击 [FINISH]
4

编译并烧录

使用调试按钮完成编译烧录。应用加载成功后,LCD 会显示一个灯泡图标。

更改 PHY 配置

RAIL/Bluetooth 示例默认使用 sub-G 频段 PHY 配置。如需修改:
1

修改 RAIL Switch 项目的 PHY

打开 RAIL Switch 项目,在 .slcp 文件中点击 Software Components,在 Advanced Configurators 下选择 Radio Configurator,点击 Open,选择新的 PHY。新配置将自动生成到 autogen/rail_config.cautogen/rail_config.h
2

同步到 Bluetooth Light 项目

打开 Soc Light Rail Dmp 项目,将 RAIL Switch 项目中生成的 rail_config.crail_config.h 复制到 Soc Light Rail Dmp 项目中,覆盖旧文件。
3

重新编译烧录

重新编译并烧录两个项目。
在具有多个 RAIL/Bluetooth 动态多协议 Light 设备和单个 Switch 设备的演示配置中,可能会发生不可预测的行为。建议使用单个 Light 设备和单个 Switch 设备进行测试。

所需组件清单

组件版本要求用途
Bluetooth SDK≥ 3.0.0Bluetooth 协议栈
Flex SDK≥ 3.0.0RAIL 库和 Proprietary 示例
Micrium OS-5 kernel随 Bluetooth SDK 附带RTOS 任务调度
EFR32 芯片≥ 512 kB 闪存运行全部软件组件
IAR-EWARM参见发行说明编译 RAIL Switch 应用(必需)

参考文档

  • UG305: Dynamic Multiprotocol User’s Guide — 动态多协议通用背景、调度器详解和优先级配置
  • AN1269: Dynamic Multiprotocol Development with Bluetooth and Proprietary on RAIL in GSDK v3.x — 本文档的详细应用笔记
  • QSG168: Proprietary Flex SDK v3.x Quick Start Guide — Flex SDK 快速入门
  • QSG169: Bluetooth® SDK v3.x Quick Start Guide — Bluetooth SDK 快速入门
  • AN1260: Integrating Silicon Labs Bluetooth® Applications with the Micrium RTOS — Micrium RTOS 集成详情

Build docs developers (and LLMs) love