4. nRF54低功耗蓝牙协议栈初始化

在 nRF54 系列上开发低功耗蓝牙应用,协议栈初始化并不是一句 bt_enable() 就能带过的动作。nRF54 使用 Nordic 新一代的协议栈组合:底层是 MPSL(Multi-Protocol Service Layer,多协议服务层),负责管理无线硬件、时钟、温度补偿与多协议时隙调度;上层是 SoftDevice Controller(SDC),实现蓝牙 LE 的链路层(Link Layer)控制器功能;再往上才是主机层(Host)与应用。理解这三层的初始化顺序与依赖关系,是后续广播、扫描、连接和功耗调优的基础。

一、三层结构:谁先启动,谁依赖谁

MPSL 是整条无线链路的“地基”。它接管 RADIO 外设、HFCLK/LFCLK 时钟源、温度传感器和 PPI/DMA 资源,并为蓝牙、802.15.4、2.4 GHz 私有协议提供统一的时隙仲裁。SDC 作为控制器,必须建立在 MPSL 之上:它通过 MPSL 申请无线时隙,通过 MPSL 获取时钟与温度补偿,从而保证链路层时序稳定。主机层(如 Zephyr 的 Bluetooth Host)再通过 HCI 与 SDC 交互。

因此初始化顺序是固定的:MPSL 初始化 → SDC 初始化 → 主机初始化 → 应用启用蓝牙。在 Zephyr 中,这一过程通常由 bt_enable() 内部按序触发,但开发者仍需理解各阶段在做什么,才能在功耗异常或连接失败时定位问题。

nRF54 蓝牙协议栈初始化与运行时依赖 应用层 Application 广播 / 扫描 / 连接 / GATT 服务 主机层 Host (Zephyr BT Host) GAP / GATT / SM / L2CAP SoftDevice Controller (SDC) 链路层:广播/扫描/连接/加密 MPSL 多协议服务层 时隙仲裁 / 时钟 / 温度补偿 nRF54 无线硬件 RADIO / HFCLK / LFCLK / TEMP 初始化顺序 1 MPSL 初始化 2 SDC 初始化 3 Host 初始化 4 bt_enable() 5 广播/扫描就绪 6 连接建立 顺序不可颠倒 否则时序/功耗异常 功耗关键点 • LFCLK 源选择 外部晶振 vs RC • 广播间隔 20ms ~ 10.24s • 连接间隔 7.5ms ~ 4s • 从机延迟 Slave Latency • 监督超时 100ms ~ 32s 参数决定平均电流

二、MPSL 与 SDC 的初始化要点

MPSL 初始化主要完成三件事:配置低频时钟(LFCLK)来源、注册协议栈所需的时隙请求、启动温度补偿。LFCLK 的选择直接决定待机功耗:使用外部 32.768 kHz 晶振(LFXO)精度高、功耗低,但需要外部器件;使用内部 RC(LFRC)可省去晶振,但精度较差,需要更频繁的校准,平均功耗反而可能更高。在 Zephyr 中通过设备树与 Kconfig 选择,例如 CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL 或 ..._RC。

SDC 初始化则负责配置控制器参数:支持的 LE 特性(如 2M PHY、Coded PHY、扩展广播)、最大连接数、广播集数量、TX 功率等。这些通过 sdc_cfg 结构体或 Zephyr 的 CONFIG_BT_LL_SOFTDEVICE_* 选项设置。初始化完成后,控制器进入可被主机调用的就绪状态。

/* 典型 Zephyr 初始化流程(伪代码示意) */
int main(void)
{
    /* 1. MPSL 由系统自动初始化,检查时钟配置 */
    /* 2. 启用蓝牙,内部依次初始化 SDC 与 Host */
    int err = bt_enable(NULL);
    if (err) {
        printk("bt_enable failed: %d\n", err);
        return err;
    }

    /* 3. 配置广播参数 */
    struct bt_le_adv_param adv_param =
        BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONN,
                        BT_GAP_ADV_FAST_INT_MIN_2,  /* 100ms */
                        BT_GAP_ADV_FAST_INT_MAX_2,  /* 150ms */
                        NULL);

    /* 4. 启动广播 */
    bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), NULL, 0);
    return 0;
}

三、广播、扫描与连接建立

广播是连接建立的前置动作。nRF54 支持传统广播与扩展广播(Extended Advertising)。传统广播在 37/38/39 三个信道轮询发送,PDU 最大 31 字节;扩展广播可使用数据信道,单包最大 255 字节,并支持周期性广播。广播间隔越短,被发现越快,但平均功耗越高。以 100 ms 间隔、0 dBm 发射为例,广播事件本身仅持续几百微秒,占空比极低,因此广播态平均电流通常在几十微安量级(示例估算,实际取决于芯片型号与配置)。

扫描分为被动扫描与主动扫描。被动扫描只接收广播包;主动扫描会额外发送 SCAN_REQ 并接收 SCAN_RSP,可获取更多信息,但会增加少量功耗。扫描窗口(Window)与扫描间隔(Interval)的比值决定占空比:例如 Interval=100 ms、Window=50 ms,占空比 50%,平均电流明显高于 10% 占空比。扫描占空比是扫描态功耗的首要调节旋钮。

连接建立由发起方(Central)在收到可连接广播后发送 CONNECT_IND,其中携带连接参数:连接间隔、从机延迟、监督超时、信道映射等。连接建立后,双方按连接间隔周期性通信。连接事件中即使没有数据,也需要保持收发窗口,因此连接间隔越短,唤醒越频繁,平均功耗越高。

四、连接参数与功耗的定量关系

连接态平均电流可近似理解为:每个连接事件消耗的能量 × 每秒连接事件数。连接事件数 = 1 / 连接间隔。若从机延迟为 N,则从机可以跳过 N 个连接事件不响应,仅在需要时唤醒,从而把有效唤醒频率降低到 1 / ((N+1) × 连接间隔)。监督超时必须大于 (1 + Slave Latency) × (Connection Interval) × 2,否则链路会被误判断开。

参数示例值对功耗的影响
广播间隔100 ms越短越易被发现,功耗越高
扫描间隔 / 窗口100 ms / 50 ms占空比 50%,扫描功耗较高
连接间隔30 ms越短响应越快,功耗越高
从机延迟4有效唤醒周期变为 150 ms
监督超时4 s需 > 2×(1+4)×30ms = 300ms
连接参数需双方协商,Central 提出、Peripheral 可请求更新。实际产品中常采用“快连接建立、慢连接维持”的策略:刚连接时用较短间隔完成服务发现,随后请求切换到长间隔 + 从机延迟以降低平均功耗。

五、初始化与运行中的常见问题

若 bt_enable() 返回负值,优先检查 MPSL 时钟配置与内存配置是否匹配;若广播启动失败,检查广播参数是否与已配置的广播集数量冲突;若连接频繁断开,检查监督超时是否满足上述不等式;若平均功耗高于预期,依次排查 LFCLK 源、广播/扫描占空比、连接间隔与从机延迟是否被正确设置。把这些参数与初始化顺序对应起来,才能在 nRF54 上做出既稳定又省电的低功耗蓝牙产品。