BLE scanning base on lte_ble_gateway and app crash

Hello, I made modifications based on the nrf9160 lte_ble_gateway demo. I modified the BLE.c file and changed the BLE connection to BLE scanning.
The scanning algorithm is as follows: idle for 1000ms, then scan for 90ms, and repeat the cycle. To ensure that the BLE scan time is not delayed for a long time, I use the K_TIMER timer. I submit work in the K_TIMER callback, and then start and stop Bluetooth scanning in the work.

I found that after scanning for a period of time, about 10-20 minutes, the application may crash.
In addition, there are many Bluetooth devices in my surrounding environment. Approximately 20 broadcast messages can be scanned within 90ms.

My own product has encountered this issue. I also reproduced this issue on the nrf9160dk_nrf9160(PCA10090 1.0.0) development board, with NCS version 2.2. The LTE modem version is 1.3.6.

Modify on lte_ble_gateway:

1. Modify the ble.c file, please see the attachment.

2. Add define in prj.conf. (CONFIG_BT_BUF_ACL_RX_SIZE=251)

3. Change the uart speed from 1000000 to 115200. (current-speed = <115200> in nrf9160dk_nrf9160_ns.overlay)

 52840 is based on hci_lpuart and only modifies the UART rate to 115200.

I tried to increase CONFIG_BT_BUF_ACL_RX_SIZE, but still encountered a crash. I am trying to reduce the number of BLE devices in the surrounding area, which will lower the probability of this problem occurring.  I speculate that it may be due to receiving a large number of Bluetooth broadcasts that the internal cache of the HCI driver is insufficient?

I hope you can help. thank you!

------------------------------

The crush log on nrf9160dk was:
[00:13:32.103,240] [1;31m<err> bt_driver: TX interrupt but no pending buffer![0m
[22:32:38.840]收←◆ASSERTION FAIL [err == 0] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/hci_core.c:335
k_sem_take failed with err -11
[00:13:42.115,631] [1;31m<err> os: r0/a1: 0x00000003 r1/a2: 0x00000000 r2/a3: 0x00000000[0m
[00:13:42.115,661] [1;31m<err> os: r3/a4: 0x00018b61 r12/ip: 0x00000000 r14/lr: 0x000119d7[0m
[00:13:42.115,661] [1;31m<err> os: xpsr: 0x41000000[0m
[00:13:42.115,692] [1;31m<err> os: Faulting instruction address (r15/pc): 0x000119e2[0m
[00:13:42.115,722] [1;31m<err> os: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0[0m
[00:13:42.115,753] [1;31m<err> os: Current thread: 0x2000ef20 (unknown)[0m
[00:13:42.160,675] [1;31m<err> fatal_error: Resetting system[0m\0
[22:32:39.667]收←◆*** Booting Zephyr OS build v3.2.99-ncs1 ***

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr/kernel.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/uuid.h>
#include <bluetooth/gatt_dm.h>
#include <bluetooth/scan.h>

#include <dk_buttons_and_leds.h>
#include <zephyr/sys/byteorder.h>

#include <net/nrf_cloud.h>
#include <zephyr/logging/log.h>
#include "aggregator.h"

LOG_MODULE_DECLARE(lte_ble_gw);


static void connected(struct bt_conn *conn, uint8_t conn_err)
{
}

static struct bt_conn_cb conn_callbacks = {
	.connected = connected,
};


static int gap_scan_num = 0;
static void ble_scan_no_filter_match(struct bt_scan_device_info *device_info, bool connectable)
{
	gap_scan_num++;
}

static void scan_timer_handler(struct k_timer *dummy);

BT_SCAN_CB_INIT(scan_cb, NULL, ble_scan_no_filter_match, NULL, NULL);
K_TIMER_DEFINE(scan_timer_id, scan_timer_handler, NULL);
static struct k_work gap_scan_worker;
static void scan_work_callback(struct k_work *work);

bool gap_is_scanning = false;
#define SCAN_INTERVAL_MS 1000

static void scan_timer_handler(struct k_timer *dummy)
{
	if (gap_is_scanning)
    {
    	k_timer_start(&scan_timer_id, K_MSEC(SCAN_INTERVAL_MS), K_NO_WAIT);
    }
    else
    {
        k_timer_start(&scan_timer_id, K_MSEC(90), K_NO_WAIT);
    }
    
	k_work_submit(&gap_scan_worker);
}


static struct bt_le_scan_param gap_scan_param =
{
	.type = BT_LE_SCAN_TYPE_PASSIVE,
	.options = (BT_LE_SCAN_OPT_FILTER_DUPLICATE),
	.interval = 0x10,
	.window = 0x10,
};

static struct bt_scan_init_param gap_scan_init =
{
	.connect_if_match = 0,
	.scan_param = &gap_scan_param,
	.conn_param = BT_LE_CONN_PARAM_DEFAULT,
};


static void scan_start(void)
{
	bt_scan_init(&gap_scan_init);
	bt_scan_cb_register(&scan_cb);

	k_timer_start(&scan_timer_id, K_MSEC(5000), K_NO_WAIT);
	LOG_INF("Scanning...");
}

static void ble_ready(int err)
{
	LOG_INF("Bluetooth ready");
	bt_conn_cb_register(&conn_callbacks);
	scan_start();
}

static void scan_work_callback(struct k_work *work)
{    	
	static uint32_t gap_total_start = 0;

	gap_total_start++;
    if (gap_is_scanning)
    {   
        int err = bt_scan_stop();
        if (err)
	    {
	        LOG_ERR("Fail to stop scan, err %d", err);
	        return;
	    }
	    else
	    {
	    	LOG_INF("Stop scan success:%d, num:%d", gap_scan_num, gap_total_start);
	    }
	    gap_is_scanning = false;
    }
    else
    {	
		gap_scan_num = 0;
        //check if need refresh scannning cfg before start scanning
        int err = bt_scan_start(BT_SCAN_TYPE_SCAN_PASSIVE);
	    if (err)
	    {
	    	LOG_ERR("Fail to start scan, err %d", err);
	    	return;
	    }
	    else
	    {
	    	LOG_INF("start scan success");
	    }
	    gap_is_scanning = true;
    }
}

/*
void nrf_ble_hardware_reset(void)
{
}
*/

void ble_init(void)
{
	int err;

	LOG_INF("Initializing Bluetooth..");
	err = bt_enable(ble_ready);
	if (err) {
		LOG_ERR("Bluetooth init failed (err %d)", err);
		return;
	}
	
    k_work_init(&gap_scan_worker, scan_work_callback);
}
9160dk_crash_log.txt

Related