BLE Advertising and breakpoints

I'm just getting started with an Adafruit ItsyBitsy nRF52840 and a Raspberry Pi Pico debugger running OpenOCD, using CLion as my IDE.

Everything works pretty well but I am having difficulty setting breakpoints if I enable BLE advertising. If I disable advertising (or rather, don't start it), then breakpoints work perfectly. But if advertising is on I get a segfault as soon as I toggle a breakpoint, even if it's not in the currently running code.

The Task-0 [idle] callstack looks like this:

z_arm_usage_fault fault_s.S:80
<signal handler called> 0x00000000fffffff1
m_assert_handler mpsl_init.c:175
sym_S2UAPMFVIQXDUOA6CV7GJMB33TYHEUH5D6LHO5Q 0x0000000000029ea8
sym_J5F7QGRFPKMLWRNSXZXS5YI7BM4DUTISCOASCOA 0x0000000000027baa
mpsl_timer0_isr_wrapper_body mpsl_init.c:130
mpsl_timer0_isr_wrapper mpsl_init.c:128
<signal handler called> 0x00000000fffffffd
arch_cpu_idle cpu_idle.S:108
k_cpu_idle kernel.h:5627
idle idle.c:83
z_thread_entry thread_entry.c:36
free_list_remove_bidx heap.c:44

And the debugger stops in fault_s.S:

SECTION_SUBSEC_FUNC(TEXT,__fault,z_arm_exc_spurious)

	mrs r0, MSP

My prj.conf looks like this:

CONFIG_SERIAL=y
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="DIY GNSS"
CONFIG_BT_ADV_PROV_DEVICE_NAME=y
CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_DEVICE_APPEARANCE=1362
CONFIG_DEBUG_OPTIMIZATIONS=y
CONFIG_DEBUG=y
CONFIG_REBOOT=y
CONFIG_THREAD_NAME=y
CONFIG_THREAD_MONITOR=y

And main.c looks like this:

#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/uuid.h>

#define BT_UUID_BASE         BT_UUID_128_ENCODE(0xc33a0000, 0xbda8, 0x4293, 0xb836, 0x10dd6d78e7a1)

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_UUID128_ALL, BT_UUID_BASE),
};

void main(void) {
    int err = bt_enable(NULL);
    if (err) {
        return;
    }

    err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
    if (err) {
        return;
    }

    while(true) {
        k_msleep(1000);
    }
}

Putting a breakpoint in the while loop causes the segfault - it doesn't even actually hit it.

Any idea what might be causing it? I know BLE timings can be fickle and the callstack mentions timer0_isr, so I thought it might have something to do with interrupts and breakpoints not playing together, but that's just wild speculation, and doesn't get me any closer to fixing the problem.

Related