Skip to content

Commit 540fb0a

Browse files
committed
modules: Pull in sending of modem traces to Memfault
Pull in sending of modem traces to Memfault Verify and test in CI Signed-off-by: Simen S. Røstad <simen.rostad@nordicsemi.no>
1 parent a569795 commit 540fb0a

File tree

6 files changed

+86
-6
lines changed

6 files changed

+86
-6
lines changed

.github/actions/build-step/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ runs:
5252
FW_TYPE=${{ inputs.memfault_fw_type }}
5353
fi
5454
cd ${{ inputs.path }}
55-
cp overlay-memfault.conf overlay-memfault-att.conf
55+
cat overlay-memfault.conf overlay-upload-modem-traces-to-memfault.conf > overlay-memfault-att.conf
5656
echo "CONFIG_MEMFAULT_NCS_PROJECT_KEY=\"${{ inputs.memfault_project_key }}\"" >> overlay-memfault-att.conf
5757
echo CONFIG_MEMFAULT_NCS_FW_TYPE=\"$FW_TYPE\" >> overlay-memfault-att.conf
5858
echo CONFIG_MEMFAULT_NCS_FW_VERSION_AUTO=y >> overlay-memfault-att.conf
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# Continuously store modem traces to flash and upload them to Memfault upon a coredump
8+
9+
# Memfault
10+
CONFIG_MEMFAULT_NCS_POST_MODEM_TRACE_ON_COREDUMP=y
11+
12+
# nRF Modem lib trace
13+
CONFIG_FCB=y
14+
CONFIG_FLASH_MAP=y
15+
CONFIG_NRF_MODEM_LIB_TRACE=y
16+
# Set the default trace level to off preventing overwriting the trace leading up to the crash after
17+
# boot. The Memfault LTE coredump modem trace layer will ensure that traces are enabled once
18+
# the coredump/modem trace has been uploaded, or if there is no application coredump.
19+
CONFIG_NRF_MODEM_LIB_TRACE_LEVEL_OFF=y
20+
CONFIG_NRF_MODEM_LIB_SHELL_TRACE=y
21+
CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_FLASH=y
22+
CONFIG_NRF_MODEM_TRACE_FLASH_NOSPACE_ERASE_OLDEST=y
23+
CONFIG_NRF_MODEM_LIB_TRACE_STACK_SIZE=1024
24+
# Maximum number of sectors that the trace backend can handle
25+
CONFIG_NRF_MODEM_LIB_TRACE_FLASH_SECTORS=255
26+
# Modem trace flash partition size with 255 sectors of 4kB each
27+
CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_FLASH_PARTITION_SIZE=0xFF000

docs/common/advanced.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
### Keep it simple - small functions, pass by reference, readability and maintainability
1818
- Explanation of keeping it simple with small functions, passing by reference, readability, and maintainability.
1919

20+
###
21+
- Document uploading modem traces to memfault and how the device can be setup with a custom data recording upload and setup with sec tags to dump TLS traffic.
22+
2023
## Useful links
2124

2225
[nRF Cloud CoAP](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/libraries/networking/nrf_cloud_coap.html)

docs/common/getting_started.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,10 @@ west build -b thingy91x/nrf9151/ns -- -DEXTRA_CONF_FILE="overlay-memfault.conf"
5858

5959
### Build with memfault and etb traces overlay
6060
```shell
61-
west build -b thingy91x/nrf9151/ns -- -DEXTRA_CONF_FILE="overlay-memfault-debug.conf;overlay-etb.conf"
61+
west build -b thingy91x/nrf9151/ns -- -DEXTRA_CONF_FILE="overlay-memfault.conf;overlay-etb.conf"
62+
```
63+
64+
### Build with memfault and uploading of modem traces to memfault on coredumps
65+
```shell
66+
west build -b thingy91x/nrf9151/ns -- -DEXTRA_CONF_FILE="overlay-memfault.conf;overlay-upload-modem-traces-to-memfault.conf"
6267
```

tests/on_target/tests/test_functional/test_memfault.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
import pytest
77
import os
88
import requests
9-
import datetime
109
import time
1110
from utils.flash_tools import flash_device, reset_device
1211
from utils.logger import get_logger
12+
from datetime import datetime, timezone
1313

1414
MEMFAULT_ORG_TOKEN = os.getenv('MEMFAULT_ORGANIZATION_TOKEN')
1515
MEMFAULT_ORG = os.getenv('MEMFAULT_ORGANIZATION_SLUG')
@@ -20,8 +20,36 @@
2020
logger = get_logger()
2121

2222
url = "https://api.memfault.com/api/v0"
23+
url_cdr = "https://app.memfault.com/api/v0"
2324
auth = ("", MEMFAULT_ORG_TOKEN)
2425

26+
def fetch_recent_modem_trace(device_id, start_time, end_time):
27+
r = requests.get(
28+
f"{url_cdr}/organizations/{MEMFAULT_ORG}/projects/{MEMFAULT_PROJ}/devices/{device_id}/custom-data-recordings?end_time={end_time}&page=1&per_page=1&start_time={start_time}",
29+
auth=auth
30+
)
31+
32+
# Print the request URL for debugging
33+
logger.debug(f"Request URL: {r.url}")
34+
# Print the response status code for debugging
35+
logger.debug(f"Response status code: {r.status_code}")
36+
# Print the response content for debugging
37+
logger.debug(f"Response content: {r.content}")
38+
39+
r.raise_for_status()
40+
response = r.json()
41+
42+
# Extract relevant data from the response
43+
data = response.get("data", [])
44+
45+
if data:
46+
recording = data[0]
47+
reason = recording.get("reason")
48+
49+
if reason == "modem traces":
50+
return recording.get("id")
51+
52+
return None
2553

2654
def get_traces(family, device_id):
2755
r = requests.get(
@@ -39,11 +67,10 @@ def get_latest_coredump_traces(device_id):
3967
return get_traces("coredump", device_id)
4068

4169
def timestamp(event):
42-
return datetime.datetime.strptime(
70+
return datetime.strptime(
4371
event["captured_date"], "%Y-%m-%dT%H:%M:%S.%f%z"
4472
)
4573

46-
4774
def test_memfault(dut_board, hex_file):
4875
# Save timestamp of latest coredump
4976
coredumps = get_latest_coredump_traces(IMEI)
@@ -81,3 +108,21 @@ def test_memfault(dut_board, hex_file):
81108
break
82109
else:
83110
raise RuntimeError("No new coredump observed")
111+
112+
# Wait for modem trace to be reported to memfault api
113+
start = time.time()
114+
now = datetime.now(timezone.utc)
115+
start_time = now.strftime("%Y-%m-%dT%H:%M:%SZ")
116+
117+
while time.time() - start < MEMFAULT_TIMEOUT:
118+
119+
now = datetime.now(timezone.utc)
120+
end_time = now.strftime("%Y-%m-%dT%H:%M:%SZ")
121+
122+
modem_trace_id = fetch_recent_modem_trace(IMEI, start_time, end_time)
123+
if modem_trace_id:
124+
print(f"Found modem trace with ID {modem_trace_id}")
125+
break
126+
time.sleep(5)
127+
else:
128+
raise RuntimeError("No modem trace observed")

west.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ manifest:
1414
- name: nrf
1515
remote: ncs
1616
repo-path: sdk-nrf
17-
revision: 52fa7533833478ecbf796c44bc5dc92e79fcbf9b
17+
revision: 76347af2dcd98467b26f28dfecb3b7bc1f57e68a
1818
import: true

0 commit comments

Comments
 (0)