Bluetooth: Memfault Diagnostic Service (MDS)

The Memfault Diagnostic Service sample demonstrates how to expose diagnostic data collected by the Memfault SDK over Bluetooth LE using nRF Connect SDK Bare Metal option. The sample advertises the Memfault Diagnostic Service (MDS) and the Battery Service. A Bluetooth gateway can connect to the device, read the Memfault upload information, and stream diagnostic chunks to the Memfault cloud.

Requirements

The sample supports the following development kits:

The following board variants do not have DFU capabilities:

S115:

Hardware platform

PCA

Board target

nRF54L15 DK

PCA10156

bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice

nRF54L15 DK (emulating nRF54L10)

PCA10156

bm_nrf54l15dk/nrf54l10/cpuapp/s115_softdevice

nRF54L15 DK (emulating nRF54L05)

PCA10156

bm_nrf54l15dk/nrf54l05/cpuapp/s115_softdevice

nRF54LM20 DK

PCA10184

bm_nrf54lm20dk/nrf54lm20a/cpuapp/s115_softdevice

nRF54LS05 DK

PCA10214

bm_nrf54ls05dk/nrf54ls05b/cpuapp/s115_softdevice

nRF54LS05 DK (emulating nRF54LS05A)

PCA10214

bm_nrf54ls05dk/nrf54ls05a/cpuapp/s115_softdevice

nRF54LV10 DK

PCA10188

bm_nrf54lv10dk/nrf54lv10a/cpuapp/s115_softdevice

S145:

Hardware platform

PCA

Board target

nRF54L15 DK

PCA10156

bm_nrf54l15dk/nrf54l15/cpuapp/s145_softdevice

nRF54L15 DK (emulating nRF54L10)

PCA10156

bm_nrf54l15dk/nrf54l10/cpuapp/s145_softdevice

nRF54L15 DK (emulating nRF54L05)

PCA10156

bm_nrf54l15dk/nrf54l05/cpuapp/s145_softdevice

nRF54LM20 DK

PCA10184

bm_nrf54lm20dk/nrf54lm20a/cpuapp/s145_softdevice

nRF54LS05 DK

PCA10214

bm_nrf54ls05dk/nrf54ls05b/cpuapp/s145_softdevice

nRF54LS05 DK (emulating nRF54LS05A)

PCA10214

bm_nrf54ls05dk/nrf54ls05a/cpuapp/s145_softdevice

nRF54LV10 DK

PCA10188

bm_nrf54lv10dk/nrf54lv10a/cpuapp/s145_softdevice

Overview

The sample uses the Memfault SDK as a module in the Bare Metal to collect coredumps, reboot reasons, metrics, and trace events from the device. Each device reports a Memfault device ID derived from its hardware ID, so that devices appear individually in the Memfault fleet view.

Data upload over Bluetooth LE

This sample does not send data to Memfault over IP. Instead, it uses the Memfault Diagnostic Service (MDS) over Bluetooth LE to stream diagnostic chunks to a gateway like nRF Connect Device Manager, which forwards them to Memfault. Firmware must call ble_mds_process() from the main loop. See Memfault Diagnostic Service (MDS) for the MDS library API and Memfault on Bare Metal for bare-metal Memfault usage rules.

Metrics

The sample defines the following application metrics in samples/bluetooth/ble_mds/memfault_config/memfault_metrics_heartbeat_config.def:

  • button_press_count - The number of button presses.

  • battery_soc_pct - The simulated battery level.

  • button_elapsed_time_ms - The time measured between two button presses.

For more information about defining and collecting metrics, see Memfault: Collecting Device Metrics.

Trace events

The sample defines the button_state_changed trace reason in samples/bluetooth/ble_mds/memfault_config/memfault_trace_reason_user_config.def. The event is collected when Button 1 changes state.

For more information about trace events, see Memfault: Error Tracking with Trace Events.

Coredumps

Press Button 3 to trigger a HardFault exception by division by zero. After reboot, reconnect with an MDS gateway to transfer the collected coredump data to Memfault.

For more information about coredumps, see Memfault: Coredumps.

User interface

LED 0:

Lit when the device is initialized.

LED 1:

Lit when a device is connected.

Button 0:

Starts or stops the button_elapsed_time_ms metric timer. The second press stops the timer and triggers a Memfault heartbeat using a deferred approach. Heartbeat deferral follows Memfault on Bare Metal.

Button 1:

Records the button_state_changed trace event on press and release.

Button 2:

Increments the button_press_count metric.

Button 3:

Simulates a crash by triggering a HardFault exception.

Configuration

You can modify the following options:

  • CONFIG_MEMFAULT_NCS_PROJECT_KEY - Your Memfault project key. The sample ships with a placeholder key used for CI builds, so set a real key before deploying (see Memfault prerequisites).

  • CONFIG_BLE_DIS_SERIAL_NUMBER - The device serial number reported over the Device Information Service. Set to the placeholder "ABCD" in this sample.

  • CONFIG_SAMPLE_BLE_DEVICE_NAME - The advertised device name. Defaults to "nRF BM Memfault".

  • CONFIG_SAMPLE_BLE_MDS_BATTERY_LEVEL_MEAS_INTERVAL - The battery level measurement interval, in milliseconds. Defaults to 1000.

  • CONFIG_MEMFAULT_LOGGING_ENABLE - Captures log messages into a Memfault RAM buffer so that they are uploaded together with the other diagnostic data. Not enabled in this sample, which also leaves the CONFIG_BLE_MDS_LOG_COLLECTION Kconfig option without effect.

The remaining Kconfig options in prj.conf set up the sample itself and are not intended to be changed. For the options of the Memfault Diagnostic Service, see Memfault Diagnostic Service (MDS). For the Memfault options, and for the Memfault SDK settings that are not exposed through Kconfig, see Memfault on Bare Metal. The sample also follows the ISR and main loop rules of Memfault on Bare Metal, with the metric timers in the button ISR and the heartbeat serialization in the main loop.

Firmware version

Memfault tags every chunk a device uploads with the software_version that the device reports, and decodes that data using the symbol file uploaded for the same version. Version handling is therefore what determines whether coredumps and trace events are readable in the Memfault web UI.

This sample derives all of its version strings from the VERSION file in the sample directory. To release a new build:

  1. Increment VERSION_MAJOR, VERSION_MINOR, or PATCHLEVEL in VERSION.

  2. Rebuild and program the sample.

  3. Upload the new zephyr.elf symbol file to Memfault, as described in Testing.

Note

Only VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, and EXTRAVERSION contribute to the reported version. Changing VERSION_TWEAK alone produces a new binary that reports an unchanged software_version, which makes Memfault decode it with the previously uploaded symbol file.

The sample Kconfig file reports the version from the VERSION file as the Memfault software_version and as the Bluetooth Device Information Service (DIS) firmware revision, so that Memfault and DIS always agree. The software type ("app") and the hardware version ("hw 54.15.0") are mapped the same way, to the DIS software revision and hardware revision. To report different values, override the corresponding Kconfig options in prj.conf. These options are set as defaults in the sample Kconfig file.

The prj.conf file also enables the CONFIG_MEMFAULT_NCS_FW_VERSION_STATIC Kconfig option, which is what makes Memfault report the version from VERSION verbatim instead of generating one at build time.

Building and running

This sample can be found under samples/bluetooth/ble_mds/ in the Bare Metal folder structure.

For details on how to create, configure, and program a sample, see Getting Started with the samples.

Testing

Test this sample with nRF Connect Device Manager after completing the Memfault prerequisites.

  1. Compile and program the application.

  2. Connect to the kit with a terminal emulator, for example the Serial Terminal app.

  3. Reset the kit.

  4. In the terminal, observe that the BLE MDS sample initialized message is printed.

  5. Observe that the Advertising as nRF BM Memfault message is printed. You can configure this name using the CONFIG_SAMPLE_BLE_DEVICE_NAME Kconfig option.

  6. Open nRF Connect Device Manager and scan for devices.

  7. Connect to the device and open the diagnostics view.

  8. Use the buttons to generate metrics, trace events, and a coredump.

  9. Upload the symbol file generated from your build to your Memfault project, so that Memfault can decode the data that the device uploads. The symbol file is located in the build folder: <build>/ble_mds/zephyr/zephyr.elf.

    1. In a web browser, open the Memfault Dashboard and select your project.

    2. Navigate to Fleet > Devices in the left side menu. You can see your newly connected device and the software version in the list.

    3. Select the software version number for your device and click Upload to upload the symbol file.

  10. Explore the Memfault web UI to inspect the uploaded data.

Memfault decodes the uploaded data using the symbol file that is linked to the software_version string the device reports, which this sample derives from the VERSION file (see Firmware version). Upload a new symbol file whenever you change VERSION or release a new firmware build. Without a matching symbol file, chunks still upload, but coredumps, trace events, and other symbolicated information appear with limited or unusable detail.

Dependencies

This sample uses the following Bare Metal libraries:

In addition, it uses the Memfault SDK.