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

nRF52832增加BLE外设连接数后无法广播的排查咨询

增加nRF52832 BLE外设连接数后无法广播的排查要点

作为嵌入式系统新手,尝试修改sdk.config中的nrf_sdh_ble_peripheral_link_count来增加nRF52832的BLE外设连接数,但调整后设备完全无法广播。相关代码如下:

static uint16_t m_connection_handle[NRF_SDH_BLE_PERIPHERAL_LINK_COUNT] = {BLE_CONN_HANDLE_INVALID};
static uint8_t m_num_connections = 0;

static void on_advertising_events(ble_adv_evt_t advertising_event)
{
    NRF_LOG_DEBUG("on_advertising_events - event: %d", advertising_event);

    ret_code_t err_code;

    switch (advertising_event)
    {
        case BLE_ADV_EVT_FAST:
            NRF_LOG_INFO("Fast advertising.");
#ifdef BOARD_PCA10040
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
#endif
            break;

        case BLE_ADV_EVT_IDLE:
            if (m_num_connections < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT)
            {
                err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
                APP_ERROR_CHECK(err_code);
            }
            break;

        default:
            break;
    }
}

static void on_ble_events(ble_evt_t const * p_ble_event, void * p_context)
{
    NRF_LOG_DEBUG("on_ble_events - event: %d", p_ble_event->header.evt_id);

    ret_code_t err_code = NRF_SUCCESS;

    switch (p_ble_event->header.evt_id)
    {
        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected - Reason: %d", p_ble_event->evt.gap_evt.params.disconnected.reason);
            m_mtu_exchanged = false;
            break;

        case BLE_GAP_EVT_CONNECTED:
        {
            NRF_LOG_INFO("Connected.");
#if BOARD_PCA10040
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
#endif
            if (m_num_connections < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT){
                m_connection_handle[m_num_connections++] = p_ble_event->evt.gap_evt.conn_handle;
            }
            // Trigger the MTU exchange timer
            NRF_LOG_INFO("Trigger MTU exchange timer.");
            if (pdPASS != xTimerStart(m_mtu_exchange_timer, OSTIMER_WAIT_FOR_QUEUE))
            {
                NRF_LOG_WARNING("Failed to start MTU exchange timer");
            }

            NRF_LOG_DEBUG("### Configuration:");
            NRF_LOG_DEBUG("### Connection Interval: %d (ms)", MAX_CONN_INTERVAL * 1.25);
            NRF_LOG_DEBUG("### Connection Event Length: %d (ms)", NRF_SDH_BLE_GAP_EVENT_LENGTH * 1.25);
            NRF_LOG_DEBUG("### Connection Event Length Extension: %d", 0);
            NRF_LOG_DEBUG("### ATT MTU: %d", NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
            NRF_LOG_DEBUG("### Data Length: %d", NRF_SDH_BLE_GAP_DATA_LENGTH);
        } break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_event->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;

        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            NRF_LOG_DEBUG("GATT Client Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_event->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            NRF_LOG_DEBUG("GATT Server Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_event->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
        {
            NRF_LOG_DEBUG("BLE_GAP_EVT_CONN_PARAM_UPDATE");

            ble_gap_conn_params_t const * p_connection = &p_ble_event->evt.gap_evt.params.conn_param_update.conn_params;
            NRF_LOG_DEBUG("max_conn_interval: %d ms", p_connection->max_conn_interval * 1.25);
            NRF_LOG_DEBUG("min_conn_interval: %d ms", p_connection->min_conn_interval * 1.25);
            NRF_LOG_DEBUG("slave_latency: %d", p_connection->slave_latency);
            NRF_LOG_DEBUG("conn_sup_timeout: %d ms",  p_connection->conn_sup_timeout * 10);
        } break;


        default:
            // No implementation needed.
            break;
    }
}
static void disconnect(uint16_t connection_handle, void * p_context)
{
    UNUSED_PARAMETER(p_context);

    ret_code_t err_code = sd_ble_gap_disconnect(connection_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", connection_handle, err_code);
    }
    else
    {
        NRF_LOG_DEBUG("Disconnected connection handle %d", connection_handle);

        // Find and remove the connection handle from the array
        for (int i = 0; i < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT; ++i)
        {
            if (m_connection_handle[i] == connection_handle)
            {
                m_connection_handle[i] = BLE_CONN_HANDLE_INVALID;
                m_num_connections--;
                break;
            }
        }

        // Restart advertising if necessary
        if (m_num_connections < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT)
        {
            start_ble_advertising(NULL); // Adjust parameters as needed
        }
    }
}

以下是需要检查的关键事项:

  • 同步调整总连接数配置:
    只修改nrf_sdh_ble_peripheral_link_count不够,必须同步调整sdk.config中的nrf_sdh_ble_total_link_count,这个参数定义了SoftDevice支持的总连接数(外设+中心角色)。如果总连接数小于外设连接数,SoftDevice初始化会直接失败,导致无法启动广播。

  • 检查内存资源是否充足:
    nRF52832只有64KB RAM,多连接会占用更多内存:

    • 增大HEAP_SIZE配置,每个BLE连接需要1-2KB左右的堆内存存储上下文,堆不足会导致SoftDevice初始化失败或运行时崩溃。
    • 查看编译后的内存使用报告,确认剩余RAM是否足够承载目标连接数的需求。
    • 降低NRF_SDH_BLE_GATT_MAX_MTU_SIZE、NRF_SDH_BLE_GAP_DATA_LENGTH等参数,过大的MTU或数据长度会额外占用RAM。
  • 验证SoftDevice初始化状态:
    在代码中检查sd_ble_enable()和nrf_sdh_enable_request()的返回值,如果返回NRF_ERROR_NO_MEM等错误码,说明资源不足导致初始化失败,无法启动广播。

  • 修复连接计数逻辑漏洞:
    当前代码仅在自定义disconnect函数中更新m_num_connections,但当远程设备主动断开触发BLE_GAP_EVT_DISCONNECTED事件时,没有处理连接计数的减少,会导致m_num_connections值错误,进而在BLE_ADV_EVT_IDLE时不会重启广播。需要在BLE_GAP_EVT_DISCONNECTED事件中调用disconnect函数,或者手动遍历m_connection_handle数组找到对应的连接句柄并更新计数。

  • 调整广播与连接参数:

    • 检查广播配置:多连接模式下,广播间隔不能设置过小,否则会占用过多无线资源,导致无法正常处理连接请求或维持现有连接。
    • 调整NRF_SDH_BLE_GAP_EVENT_LENGTH:连接事件长度需要适配多连接场景,确保每个连接都有足够的时间完成通信,否则会导致连接不稳定或广播无法启动。
    • 优化连接间隔:如果连接间隔设置过小,会让无线资源被现有连接占满,无法腾出时间进行广播。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:23:09