BLE Advertisement does not update after reflashing

Hello. I have been reading quite a bit about the BLE technology and after some time I have decided to start some hands on practise myself.

I use:

  • NCS v2.5.0
  • nRF52840DK nRF52840 development board

I have initially started with peripheral_ht sample project that is available in C:\ncs\v2.5.0\samples\bluetooth.

I have stripped down this project as much as I could and I got left with the very basic BLE code that only does some basic advertising. See the full source code:

/* main.c - Application main entry point */

/*
 * Copyright (c) 2019 Aaron Tsui <[email protected]>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/kernel.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main);

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR))};

static void connected(struct bt_conn *conn, uint8_t err)
{
	if (err)
	{
		LOG_ERR("Connection failed (err 0x%02x)\n", err);
	}
	else
	{
		LOG_INF("Connected\n");
	}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	LOG_ERR("Disconnected (reason 0x%02x)\n", reason);
}

static void bt_ready(void)
{
	int err;

	LOG_INF("Bluetooth initialized\n");

	err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err)
	{
		LOG_ERR("Advertising failed to start (err %d)\n", err);
		return;
	}

	LOG_INF("Advertising successfully started\n");
}

int main(void)
{
	int err;

	err = bt_enable(NULL);
	if (err)
	{
		LOG_INF("Bluetooth init failed (err %d)\n", err);
		return 0;
	}

	bt_ready();

	/* Implement indicate. At the moment there is no suitable way
	 * of starting delayed work so we do it here
	 */
	while (1)
	{
		k_sleep(K_SECONDS(1));
		LOG_INF("hello world \n");
	}
	return 0;
}

and my prj.conf:

CONFIG_BT=y
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Lukas test device"
CONFIG_CBPRINTF_FP_SUPPORT=y

After experimenting with it for a few hours, I have found 2 critical issues:

1. Modifying advertisement data and reflashing the device does not really update the advertisement packets.

For example, from the code above, you can see that my current advertisement data looks as following:

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR))};

But when I flash the device and monitor it through my Android phone (nRF Connect app), I can see that there are 3 services being advertised. I cannot wrap my head around why Health Thermometer is being advertised since I do not have anything in my code related to Health Thermometer. See image I have captured on my phone:

Additionally, I have tried to update my advertisment data by adding something to it. I have added Battery Service:

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BAS_VAL))};

To ensure that I have flashed the device correctly, I have also changed BT device name:

After reflashing the device, I can confirm that BT device name is changed but the advertisement has still not updated:

2. Cannot debug the code using breakpoints

Out of curiosity, I have tried to step through the code using breakpoints. I have noticed that after 

    
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
function is called and I have breakpoint on the next line, the device will crash:
See the screenshot below ( I have breakpoint at LOG_INF("Advertising Successfully started\n")
The logs:
*** Booting nRF Connect SDK v2.5.0 ***
[00:00:00.003,875] [1B][0m<inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 
                                            c5 93 ba a9 14 4d 8d 05  30 4e 9b 92 d7 71 1e e8 |.....M.. 0N...q..
                                            aa 02 50 3c                                      |..P<             [1B][0m
[00:00:00.035,308] [1B][0m<inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)[1B][0m
[00:00:00.043,395] [1B][0m<inf> bt_hci_core: HW Variant: nRF52x (0x0002)[1B][0m
[00:00:00.050,170] [1B][0m<inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 197.47763 Build 2370639017[1B][0m
[00:00:00.062,530] [1B][0m<inf> bt_hci_core: Identity: EE:78:3D:EF:1C:E6 (random)[1B][0m
[00:00:00.070,098] [1B][0m<inf> bt_hci_core: HCI: version 5.4 (0x0d) revision 0x1102, manufacturer 0x0059[1B][0m
[00:00:00.079,803] [1B][0m<inf> bt_hci_core: LMP: version 5.4 (0x0d) subver 0x1102[1B][0m
[00:00:01.712,036] [1B][0m<inf> main: Bluetooth initialized
[1B][0m
[00:00:06.998,870] [1B][1;31m<err> mpsl_init: MPSL ASSERT: 112, 2185[1B][0m
[00:00:07.020,141] [1B][1;31m<err> os: ***** HARD FAULT *****[1B][0m
[00:00:07.040,740] [1B][1;31m<err> os:   Fault escalation (see below)[1B][0m
[00:00:07.062,042] [1B][1;31m<err> os: ARCH_EXCEPT with reason 3
[1B][0m
[00:00:07.083,007] [1B][1;31m<err> os: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000000[1B][0m
[00:00:07.106,811] [1B][1;31m<err> os: r3/a4:  0x20002354 r12/ip:  0x00000000 r14/lr:  0x0002051f[1B][0m
[00:00:07.130,645] [1B][1;31m<err> os:  xpsr:  0x41000018[1B][0m
[00:00:07.150,909] [1B][1;31m<err> os: Faulting instruction address (r15/pc): 0x000198c2[1B][0m
[00:00:07.173,950] [1B][1;31m<err> os: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0[1B][0m
[00:00:07.196,685] [1B][1;31m<err> os: Fault during interrupt handling
[1B][0m
[00:00:07.218,200] [1B][1;31m<err> os: Current thread: 0x200021e0 (unknown)[1B][0m
[00:00:07.259,918] [1B][1;31m<err> fatal_error: Resetting system[1B][0m
*** Booting nRF Connect SDK v2.5.0 ***
[00:00:00.003,875] [1B][0m<inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 
                                            c5 93 ba a9 14 4d 8d 05  30 4e 9b 92 d7 71 1e e8 |.....M.. 0N...q..
                                            aa 02 50 3c                                      |..P<             [1B][0m
[00:00:00.035,308] [1B][0m<inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)[1B][0m
[00:00:00.043,395] [1B][0m<inf> bt_hci_core: HW Variant: nRF52x (0x0002)[1B][0m
[00:00:00.050,140] [1B][0m<inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 197.47763 Build 2370639017[1B][0m
[00:00:00.062,530] [1B][0m<inf> bt_hci_core: Identity: EE:78:3D:EF:1C:E6 (random)[1B][0m
[00:00:00.070,098] [1B][0m<inf> bt_hci_core: HCI: version 5.4 (0x0d) revision 0x1102, manufacturer 0x0059[1B][0m
[00:00:00.079,833] [1B][0m<inf> bt_hci_core: LMP: version 5.4 (0x0d) subver 0x1102[1B][0m
Is there any particular reason why that happens? How can I debug my code in that case in the future if using a breakpoint cause the system to crash?

My project source files can be accessed here:
Thanks in advance for all the help !
Parents
  • hat there are 3 services being advertised.

    Wrong usage of terminology here.

    Your screenshots show services after connection and service discovery but not what is in the advertising packet(s). That is displayed in the nrf connect app in the "scanner" column that is to the left and thus invisible.

    The softdevice/bluetooth stack checks if the app code could obey the stric bluetooth timings and faults whenever these are not met - especially if the CPU was halted in a breakpoint or in an interrupt handler that had too "high" priority (which is a low value in ARM NVIC).

  • Your screenshots show services after connection and service discovery

    Yeah your are probably right, I am probably not using the correct terminology here. I am still very new to BLE so apologies for that, but you understand what I meant?

    In the screenshot, you see Health Thermometer primary service. How did that even get there since in my code I do not have anything related to Hearth Thermometer at all? I just simply have the most basic BLE peripheral example that I can do using Zephyr and that should not have any Health Thermometer services at all



    Regarding the crash during the breakpoint - that makes sense. But in that case how would I debug the code if I have any problems since I cannot use breakpoints?

  • Hi,

    Instead of stripping down existing project, you could potentially look at how to set advertising data in the BLE Fundamentals course

    Best regards,
    Dejan

  • I appreciate your suggestion and I will go through the course but that is not the point. I am interested in debugging this issue as I am convinced that this is a bug and there should not be HTS service in my simple BLE example code. I dont know whole lot about BLE but I know enough to understand that this is not how it supposed to work.

    Instead of suggesting various things, why dont you take a minute to try this out yourself and you will recreate the issue and realize that this should not happen. 

  • I was wrong, HTS is actually its own source file in the example code (hts.c in src directory) and not activated via Kconfig nor device tree.

    Double check that this file is not actually present in your code - it does not need any calls from main() to be active.

    Some devices can cache device discovery data. NRF connect has a "Refresh services" menu option that should read service definitions fresh from the device.

  • Are you referrng to this:

    If yes, that did not do anything.



    Experiment #2

    To test if I can add new services, I have added the following to my code:

    static const struct bt_data ad[] = {
    	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    	BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BAS_VAL))};
    

    and in my prj.conf I have enabled:

    CONFIG_BT_BAS=y
    After flashing the device and opening nRF Connect on my mobile phone, I see the new Battery Service appear but Health Thermometer still persists:
    I have also tried on multiple phones and all phones provided same results.
    The experiment above proves that:
    • nRF52 device is capable of adding new service (Just like I added Battery Service)
    • There is still no logical explanation on why the Health Thermometer service appears
    • The issue regarding Health Thermometer persists on different devices (multiple phones).

    I am really hoping that we can get to the bottom of this as this is really frustrating.

  • Look at the actual project files in the src folder, I bet there is a hts.c in there.

Reply Children
  • You are totally right. I had hts.c file in my project and that had an effect (even though no functions were called.

    Not going to lie, this must be the dumbest thing I have seen in my programming experience. Just by having .c file in your project without any function calls there was a automatically a BLE service added. This person who wrote this code should be sent to prison.

    Thank you for helping me out.

Related