Skip to content

Commit cfee351

Browse files
committed
samples: bluetooth: add ble_mds sample
Adds Memfault sample Signed-off-by: hlord2000 <kellyhlord@gmail.com>
1 parent 97c7d5d commit cfee351

9 files changed

Lines changed: 832 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
cmake_minimum_required(VERSION 3.20.0)
7+
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
project(ble_mds)
10+
11+
target_sources(app PRIVATE src/main.c)
12+
13+
zephyr_include_directories(memfault_config)

samples/bluetooth/ble_mds/Kconfig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
menu "Bluetooth LE MDS sample"
8+
9+
config SAMPLE_BLE_DEVICE_NAME
10+
string "Device name"
11+
default "Nordic_Memfault"
12+
13+
config SAMPLE_BLE_MDS_BATTERY_LEVEL_MEAS_INTERVAL
14+
int "Battery level measurement interval (ms)"
15+
default 1000
16+
help
17+
Battery level measurement interval in milliseconds.
18+
19+
config SAMPLE_BLE_MDS_RUN_LED_BLINK_INTERVAL
20+
int "Run LED blink interval (ms)"
21+
default 1000
22+
help
23+
Run status LED blink interval in milliseconds.
24+
25+
module=SAMPLE_BLE_MDS
26+
module-str=BLE Memfault Diagnostic Service Sample
27+
source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config"
28+
29+
endmenu # "Bluetooth LE MDS sample"
30+
31+
source "Kconfig.zephyr"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
.. _ble_mds_sample:
2+
3+
Bluetooth: Memfault Diagnostic Service (MDS)
4+
############################################
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
The Memfault Diagnostic Service sample demonstrates how to expose diagnostic data collected by the `Memfault SDK`_ over Bluetooth LE using |BMlong|.
11+
The sample advertises the Memfault Diagnostic Service (MDS) and the Battery Service.
12+
A Bluetooth gateway can connect to the device, read the Memfault upload information, and stream diagnostic chunks to the Memfault cloud.
13+
14+
Requirements
15+
************
16+
17+
The sample supports the following development kits:
18+
19+
.. tabs::
20+
21+
.. group-tab:: Simple board variants
22+
23+
The following board variants do **not** have DFU capabilities:
24+
25+
.. include:: /includes/supported_boards_all_non-mcuboot_variants_s115.txt
26+
27+
.. include:: /includes/supported_boards_all_non-mcuboot_variants_s145.txt
28+
29+
.. group-tab:: MCUboot board variants
30+
31+
The following board variants have DFU capabilities:
32+
33+
.. include:: /includes/supported_boards_all_mcuboot_variants_s115.txt
34+
35+
.. include:: /includes/supported_boards_all_mcuboot_variants_s145.txt
36+
37+
Overview
38+
********
39+
40+
The sample uses the bare-metal SoftDevice Bluetooth libraries to initialize advertising, the Battery Service, the Device Information Service, and MDS.
41+
The Memfault SDK collects reboot information, logs, metrics, trace events, and coredumps.
42+
When an MDS gateway subscribes to the Data Export characteristic and enables streaming, the application calls :c:func:`ble_mds_process` from the main loop to send pending Memfault chunks.
43+
44+
Metrics
45+
=======
46+
47+
The sample defines the following application metrics in :file:`samples/bluetooth/ble_mds/memfault_config/memfault_metrics_heartbeat_config.def`:
48+
49+
* ``button_press_count`` - The number of **Button 2** presses.
50+
* ``battery_soc_pct`` - The simulated battery level.
51+
* ``button_elapsed_time_ms`` - The time measured between two **Button 0** presses.
52+
53+
Pressing **Button 0** the second time stops the timer and triggers a heartbeat collection.
54+
55+
Trace events
56+
============
57+
58+
The sample defines the ``button_state_changed`` trace reason in :file:`samples/bluetooth/ble_mds/memfault_config/memfault_trace_reason_user_config.def`.
59+
The event is collected when **Button 1** changes state.
60+
61+
Core dumps
62+
==========
63+
64+
Press **Button 3** to trigger a hardfault exception by division by zero.
65+
After reboot, reconnect with an MDS gateway to transfer the collected coredump data to Memfault.
66+
67+
User interface
68+
**************
69+
70+
LED 0:
71+
Blinks while the sample is running.
72+
73+
LED 1:
74+
Lit when a Bluetooth LE central is connected.
75+
76+
Button 0:
77+
Starts or stops the ``button_elapsed_time_ms`` metric timer.
78+
The second press stops the timer and triggers a Memfault heartbeat.
79+
80+
Button 1:
81+
Triggers the ``button_state_changed`` trace event on press and release.
82+
83+
Button 2:
84+
Increments the ``button_press_count`` metric and triggers a Memfault heartbeat.
85+
86+
Button 3:
87+
Simulates a crash by triggering a hardfault exception.
88+
89+
Configuration
90+
*************
91+
92+
The sample configuration is split between the :file:`prj.conf` file and sample-specific Kconfig options in :file:`Kconfig`.
93+
94+
Set :kconfig:option:`CONFIG_MEMFAULT_NCS_PROJECT_KEY` to the project key for your Memfault project before using a real gateway.
95+
The sample uses :kconfig:option:`CONFIG_MEMFAULT_NCS_DEVICE_ID_HW_ID` with :kconfig:option:`CONFIG_HW_ID_LIBRARY_SOURCE_DEVICE_ID` so each device reports a hardware-derived Memfault device ID.
96+
It selects :kconfig:option:`CONFIG_MEMFAULT_REBOOT_REASON_GET_BASIC` for compatibility across the bare-metal board variants supported by this sample.
97+
You can configure the advertising name with the :kconfig:option:`CONFIG_SAMPLE_BLE_DEVICE_NAME` Kconfig option.
98+
99+
The MDS library settings use the ``CONFIG_BLE_MDS`` prefix.
100+
For Memfault SDK options that are not configurable through Kconfig, use :file:`samples/bluetooth/ble_mds/memfault_config/memfault_platform_config.h`.
101+
102+
Building and running
103+
********************
104+
105+
This sample can be found under :file:`samples/bluetooth/ble_mds/` in the |BMshort| folder structure.
106+
107+
For details on how to create, configure, and program a sample, see :ref:`getting_started_with_the_samples`.
108+
109+
Testing
110+
=======
111+
112+
You can test this sample using `nRF Connect Device Manager`_ or another MDS-compatible Bluetooth gateway.
113+
114+
1. Configure :kconfig:option:`CONFIG_MEMFAULT_NCS_PROJECT_KEY` for your Memfault project.
115+
#. Compile and program the application.
116+
#. Connect to the kit with a terminal emulator, for example the `Serial Terminal app`_.
117+
#. Reset the kit.
118+
#. In the terminal, observe that the ``BLE MDS sample initialized`` message is printed.
119+
#. Observe that the ``Advertising as nRF_BM_MDS`` message is printed.
120+
You can configure this name using the :kconfig:option:`CONFIG_SAMPLE_BLE_DEVICE_NAME` Kconfig option.
121+
#. Open `nRF Connect Device Manager`_ and scan for devices.
122+
#. Connect to the device and open the diagnostics view.
123+
#. Use the buttons to generate metrics, trace events, and a coredump.
124+
#. Upload the generated symbol file from the build directory to your Memfault project so that uploaded data can be decoded.
125+
126+
Dependencies
127+
************
128+
129+
This sample uses the following |BMshort| libraries:
130+
131+
* :c:func:`ble_adv_init`
132+
* :c:func:`ble_bas_init`
133+
* :c:func:`ble_dis_init`
134+
* :c:func:`ble_mds_init`
135+
* :c:func:`bm_buttons_init`
136+
* :c:func:`bm_timer_init`
137+
138+
In addition, it uses the `Memfault SDK`_.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/* Application-specific metrics can be defined here.
2+
* Please refer to https://docs.memfault.com/docs/embedded/metrics-api for more details.
3+
*/
4+
5+
MEMFAULT_METRICS_KEY_DEFINE(button_press_count, kMemfaultMetricType_Unsigned)
6+
MEMFAULT_METRICS_KEY_DEFINE(button_elapsed_time_ms, kMemfaultMetricType_Timer)
7+
MEMFAULT_METRICS_KEY_DEFINE(battery_soc_pct, kMemfaultMetricType_Unsigned)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2022 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*
6+
*
7+
* Platform overrides for the default configuration settings in the
8+
* memfault-firmware-sdk. Default configuration settings can be found in
9+
* "<NCS folder>/modules/lib/memfault-firmware-sdk/components/include/memfault/default_config.h"
10+
*/
11+
12+
/* SoftDevice owns HardFault_Handler for vector forwarding. Use the C hook that
13+
* the SoftDevice forwarder calls when a fault belongs to the application.
14+
*/
15+
#define MEMFAULT_EXC_HANDLER_HARD_FAULT C_HardFault_Handler
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* Application-specific trace reasons can be defined here.
2+
* Please refer to https://docs.memfault.com/docs/embedded/trace-events for more details.
3+
*/
4+
5+
MEMFAULT_TRACE_REASON_DEFINE(button_state_changed)

samples/bluetooth/ble_mds/prj.conf

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Logging
2+
CONFIG_LOG=y
3+
CONFIG_LOG_BACKEND_BM_UARTE=y
4+
5+
# SoftDevice
6+
CONFIG_SOFTDEVICE=y
7+
CONFIG_NRF_SDH_BLE_VS_UUID_COUNT=1
8+
CONFIG_NRF_SDH_BLE_GATT_MAX_MTU_SIZE=247
9+
10+
# Enable RNG
11+
CONFIG_NRF_SECURITY=y
12+
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
13+
CONFIG_PSA_WANT_GENERATE_RANDOM=y
14+
15+
# Advertising library
16+
CONFIG_BLE_ADV=y
17+
18+
# BLE connection parameters
19+
CONFIG_BLE_CONN_PARAMS=y
20+
CONFIG_BLE_CONN_PARAMS_DATA_LENGTH_TX=251
21+
CONFIG_BLE_CONN_PARAMS_DATA_LENGTH_RX=251
22+
CONFIG_BLE_CONN_PARAMS_INITIATE_ATT_MTU_EXCHANGE=y
23+
CONFIG_BLE_CONN_PARAMS_INITIATE_DATA_LENGTH_UPDATE=y
24+
25+
# Device information service
26+
CONFIG_BLE_DIS=y
27+
CONFIG_BLE_DIS_SERIAL_NUMBER="ABCD"
28+
CONFIG_BLE_DIS_HW_REVISION="hw 54.15.0"
29+
CONFIG_BLE_DIS_FW_REVISION="fw 17.2.0"
30+
CONFIG_BLE_DIS_SW_REVISION="sw 1.0.0"
31+
32+
# Battery service
33+
CONFIG_BLE_BAS=y
34+
35+
# Memfault Diagnostic Service
36+
CONFIG_BLE_MDS=y
37+
38+
# Buttons and timers
39+
CONFIG_BM_TIMER=y
40+
CONFIG_BM_BUTTONS=y
41+
CONFIG_BM_GPIOTE=y
42+
43+
# Memfault
44+
CONFIG_MEMFAULT=y
45+
CONFIG_MEMFAULT_LOGGING_ENABLE=y
46+
CONFIG_MEMFAULT_LOG_LEVEL_INF=y
47+
CONFIG_MEMFAULT_NCS_STACK_METRICS=n
48+
CONFIG_MEMFAULT_METRICS_DEFAULT_SET_ENABLE=n
49+
CONFIG_MEMFAULT_METRICS_THREADS=n
50+
CONFIG_MEMFAULT_METRICS_TIMER_CUSTOM=y
51+
CONFIG_MEMFAULT_REBOOT_REASON_GET_BASIC=y
52+
CONFIG_MEMFAULT_SOFTWARE_WATCHDOG_CUSTOM=y
53+
CONFIG_MEMFAULT_COREDUMP_COLLECT_KERNEL_REGION=n
54+
CONFIG_MEMFAULT_COREDUMP_COLLECT_TASKS_REGIONS=n
55+
56+
CONFIG_MEMFAULT_NCS_PROJECT_KEY=""
57+
CONFIG_MEMFAULT_NCS_DEVICE_ID_HW_ID=y
58+
CONFIG_HW_ID_LIBRARY_SOURCE_DEVICE_ID=y
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
sample:
2+
name: Bluetooth LE Memfault Diagnostic Service Sample
3+
tests:
4+
sample.ble_mds:
5+
sysbuild: true
6+
build_only: true
7+
extra_configs:
8+
- CONFIG_MEMFAULT_NCS_PROJECT_KEY="dummy-key"
9+
integration_platforms:
10+
- bm_nrf54l15dk/nrf54l05/cpuapp/s145_softdevice
11+
- bm_nrf54lm20dk/nrf54lm20a/cpuapp/s115_softdevice
12+
platform_allow:
13+
- bm_nrf54l15dk/nrf54l05/cpuapp/s115_softdevice
14+
- bm_nrf54l15dk/nrf54l05/cpuapp/s115_softdevice/mcuboot
15+
- bm_nrf54l15dk/nrf54l05/cpuapp/s145_softdevice
16+
- bm_nrf54l15dk/nrf54l05/cpuapp/s145_softdevice/mcuboot
17+
- bm_nrf54l15dk/nrf54l10/cpuapp/s115_softdevice
18+
- bm_nrf54l15dk/nrf54l10/cpuapp/s115_softdevice/mcuboot
19+
- bm_nrf54l15dk/nrf54l10/cpuapp/s145_softdevice
20+
- bm_nrf54l15dk/nrf54l10/cpuapp/s145_softdevice/mcuboot
21+
- bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice
22+
- bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot
23+
- bm_nrf54l15dk/nrf54l15/cpuapp/s145_softdevice
24+
- bm_nrf54l15dk/nrf54l15/cpuapp/s145_softdevice/mcuboot
25+
- bm_nrf54lm20dk/nrf54lm20a/cpuapp/s115_softdevice
26+
- bm_nrf54lm20dk/nrf54lm20a/cpuapp/s115_softdevice/mcuboot
27+
- bm_nrf54lm20dk/nrf54lm20a/cpuapp/s145_softdevice
28+
- bm_nrf54lm20dk/nrf54lm20a/cpuapp/s145_softdevice/mcuboot
29+
- bm_nrf54ls05dk/nrf54ls05b/cpuapp/s115_softdevice
30+
- bm_nrf54ls05dk/nrf54ls05b/cpuapp/s115_softdevice/mcuboot
31+
- bm_nrf54ls05dk/nrf54ls05b/cpuapp/s145_softdevice
32+
- bm_nrf54ls05dk/nrf54ls05b/cpuapp/s145_softdevice/mcuboot
33+
- bm_nrf54lv10dk/nrf54lv10a/cpuapp/s115_softdevice
34+
- bm_nrf54lv10dk/nrf54lv10a/cpuapp/s115_softdevice/mcuboot
35+
- bm_nrf54lv10dk/nrf54lv10a/cpuapp/s145_softdevice
36+
- bm_nrf54lv10dk/nrf54lv10a/cpuapp/s145_softdevice/mcuboot
37+
tags: ci_build

0 commit comments

Comments
 (0)