You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

nRF SDK问题:BLE GATT Server与中断同时运行故障排查

问题

使用nRF52DK作为BLE GATT Server,同时通过中断跟踪设备当前时间。单独启用BLE或中断功能时均正常,但同时启用时出现中断处理故障。使用环境为nRF Connect SDK 2.4.1,用到nrfx_rtc.h和bluetooth/gatt_dm.h库。

核心疑问

定时器中断是否与BLE库存在冲突?

主代码

/**
 * @file main.c
 * @brief Ajoittaja main
 * @author Kasperi Kiviluoma
 * @license MIT
 */

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

#include "bluetooth.h"
#include "timer.h"

LOG_MODULE_REGISTER(Ajoittaja, LOG_LEVEL_DBG);

Time now = {thursday, 21, 59, 50};

Schedule mon[] = {{7, 0, 0, 3600}, {20, 0, 0, 7200}};
Schedule tue[] = {{7, 0, 0, 3600}, {20, 0, 0, 7200}};
Schedule wed[] = {{7, 0, 0, 3600}, {20, 0, 0, 7200}};
Schedule thu[] = {{7, 0, 0, 3600}, {20, 0, 0, 7200}};
Schedule fri[] = {{7, 0, 0, 3600}, {20, 0, 0, 7200}};
Schedule sat[] = {{20, 0, 0, 7200}};
Schedule sun[] = {{20, 0, 0, 7200}};
Schedule *schedules[] = {mon, tue, wed, thu, fri, sat, sun};

int main(void) {
    int err;

    printk("Starting GATT Discovery Manager example\n");

    err = bluetooth_init();

    printk("Advertising successfully started\n");

    // Init GPIO
    if (gpio_init() != 0) {
        LOG_ERR("GPIO init failed");
        return -1;
    }

    // Init RTC0, 125ms counter period
    if (rtc_init(4095, time_rtc, time_handler, true) != NRFX_SUCCESS) {
        LOG_ERR("RTC0 init failed");
        return -1;
    }

    // Init RTC2
    if (rtc_init(4095, schedule_rtc, schedule_handler, false) != NRFX_SUCCESS) {
        LOG_ERR("RTC2 init failed");
        return -1;
    }

    // Init IRQs
    manual_isr_setup();

    // TODO: Low power sleep
    while (true) {
        k_sleep(K_MSEC(10));
    }

    return 0;   // Should never reach this
}

故障日志

[00:00:02.520,111] <inf> bt_sdc_hci_driver: hci_driver_open: SoftDevice Controller build revision: 
                                            e0 7e 2e c1 5e 05 85 23  46 15 dc fa 8e 29 7d 70 |.~..^..# F....)}p
                                            10 93 a5 fc                                      |....             
[00:00:02.523,864] <inf> bt_hci_core: hci_vs_init: HW Platform: Nordic Semiconductor (0x0002)
[00:00:02.523,895] <inf> bt_hci_core: hci_vs_init: HW Variant: nRF52x (0x0002)
[00:00:02.523,925] <inf> bt_hci_core: hci_vs_init: Firmware: Standard Bluetooth controller (0x00) Version 224.11902 Build 2231721665
[00:00:02.525,390] <inf> bt_hci_core: bt_dev_show_info: Identity: EB:B6:AB:2B:10:65 (random)
[00:00:02.525,451] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.4 (0x0d) revision 0x1077, manufacturer 0x0059
[00:00:02.525,482] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.4 (0x0d) subver 0x1077
[00:00:03.458,618] <err> mpsl_init: m_assert_handler: MPSL ASSERT: 112, 2134
[00:00:03.458,648] <err> os: hard_fault: ***** HARD FAULT *****
[00:00:03.458,648] <err> os: hard_fault:   Fault escalation (see below)
[00:00:03.458,679] <err> os: hard_fault: ARCH_EXCEPT with reason 3

[00:00:03.458,709] <err> os: esf_dump: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000009
[00:00:03.458,709] <err> os: esf_dump: r3/a4:  0x20001648 r12/ip:  0x20000ea0 r14/lr:  0x000138a5
[00:00:03.458,740] <err> os: esf_dump:  xpsr:  0x41000018
[00:00:03.458,770] <err> os: esf_dump: Faulting instruction address (r15/pc): 0x00020f04
[00:00:03.458,801] <err> os: z_fatal_error: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
[00:00:03.458,831] <err> os: z_fatal_error: Fault during interrupt handling

[00:00:03.458,862] <err> os: z_fatal_error: Current thread: 0x20002968 (unknown)
�00:00:09.921,539] <err> fatal_error: k_sys_fatal_error_handler: Resetting system

分析与解决

冲突原因

日志中的MPSL ASSERT: 112, 2134是关键线索,对应RTC资源被非法占用。在nRF Connect SDK中,SoftDevice(BLE控制器)默认占用RTC0用于蓝牙时序同步,而你直接通过nrfx_rtc.h初始化RTC0,与SoftDevice的资源使用产生冲突,触发硬件故障。此外,manual_isr_setup()手动修改中断向量表,干扰了Zephyr内核和SoftDevice的中断管理流程,进一步加剧冲突。

修复步骤

  1. 更换RTC实例:放弃使用RTC0,改用RTC1或RTC2(可将原RTC0的功能迁移到RTC1)。SoftDevice不会占用这两个实例,避免资源冲突。
  2. 使用Zephyr原生API:替换nrfx_rtc.h为Zephyr提供的zephyr/drivers/timer.h或zephyr/kernel.h定时器API,Zephyr会自动处理与SoftDevice的资源协调。
  3. 移除手动中断配置:删除manual_isr_setup()调用,由Zephyr内核和SoftDevice自动管理中断向量与优先级。若需自定义中断,使用IRQ_CONNECT()宏注册,确保应用层中断优先级低于SoftDevice。
  4. 验证资源占用:SoftDevice默认占用RTC0、TIMER0/TIMER1(依蓝牙配置而定)及部分GPIO,应用层初始化硬件前需确认未占用这些资源。

内容的提问来源于stack exchange,提问作者ussak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:35:56