Skip to content

Commit 5b833a7

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 1.30.1 (Build 15397)
1 parent 2d0fd16 commit 5b833a7

File tree

12 files changed

+148
-76
lines changed

12 files changed

+148
-76
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to
77
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88

9+
## [1.30.1] - 2025-10-03
10+
11+
This is a patch release, fixing one bug and applying a minor code quality
12+
improvement to the Python tooling files.
13+
14+
### 🐛 Fixed
15+
16+
- nRF-Connect SDK:
17+
18+
- Fixed an issue where panic logs generated from ISRs caused a double fault
19+
for Nordic nRF91 users where `CONFIG_LOG_MODE_IMMEDIATE=n` and
20+
`MEMFAULT_LOG_TIMESTAMPS_ENABLE` is 1.
21+
22+
- General:
23+
24+
- Added Python type annotations to the files in the `tasks` directory.
25+
926
## [1.30.0] - 2025-09-23
1027

1128
This is a minor release. Highlights:

VERSION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
BUILD ID: 15332
2-
GIT COMMIT: a6e147605b
3-
VERSION: 1.30.0
1+
BUILD ID: 15397
2+
GIT COMMIT: 1aae918e39
3+
VERSION: 1.30.1

components/include/memfault/version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ typedef struct {
2020
} sMfltSdkVersion;
2121

2222
#define MEMFAULT_SDK_VERSION \
23-
{ .major = 1, .minor = 30, .patch = 0 }
24-
#define MEMFAULT_SDK_VERSION_STR "1.30.0"
23+
{ .major = 1, .minor = 30, .patch = 1 }
24+
#define MEMFAULT_SDK_VERSION_STR "1.30.1"
2525

2626
#ifdef __cplusplus
2727
}

ports/zephyr/common/memfault_logging.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,11 @@ typedef struct MfltLogProcessCtx {
104104
#endif
105105

106106
static void prv_log_process(const struct log_backend *const backend, union log_msg_generic *msg) {
107-
// This can be called in IMMEDIATE mode from an ISR, so in that case,
108-
// immediately bail. We currently can't safely serialize to the Memfault
109-
// buffer from ISR context
110-
#if CONFIG_LOG_MODE_IMMEDIATE
107+
// This can be called in IMMEDIATE mode from an ISR or when flushing logs via LOG_PANIC, so
108+
// immediately bail. We currently can't safely serialize to the Memfault buffer from ISR context
111109
if (memfault_arch_is_inside_isr()) {
112110
return;
113111
}
114-
#endif
115112

116113
// Copied flagging from Zephry's ring buffer (rb) implementation.
117114
const uint32_t flags = IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP) ?
@@ -166,16 +163,14 @@ LOG_BACKEND_DEFINE(log_backend_mflt, log_backend_mflt_api, true);
166163

167164
// Tie Memfault's log function to the Zephyr buffer sender. This is *the* connection to Memfault.
168165
static int prv_log_out(uint8_t *data, size_t length, void *ctx) {
169-
#if defined(CONFIG_LOG_MODE_IMMEDIATE)
170-
// In synchronous mode, logging can occur from ISRs. The zephyr fault handlers are chatty so
171-
// don't save info while in an ISR to avoid wrapping over the info we are collecting.
172-
// This function may also be run from LOG_PANIC. We also want to skip saving data in this case
173-
// because the context object uses local stack memory which may not be valid when run from
174-
// LOG_PANIC
166+
// In IMMEDIATE mode, logging can occur from ISRs. The zephyr fault handlers are chatty so don't
167+
// save info while in an ISR to avoid wrapping over the info we are collecting. This function may
168+
// also be run from LOG_PANIC. We also want to skip saving data in this case because we currently
169+
// can't safely serialize to the Memfault buffer from ISR context and the context object uses
170+
// local stack memory which may not be valid when run from LOG_PANIC
175171
if (memfault_arch_is_inside_isr()) {
176172
return (int)length;
177173
}
178-
#endif
179174

180175
sMfltLogProcessCtx *mflt_ctx = (sMfltLogProcessCtx *)ctx;
181176
size_t save_length = length;

tasks/esp32.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33
# See LICENSE for details
44
#
55

6+
from __future__ import annotations
7+
68
import os
79
import re
810
import shutil
911
import sys
12+
from typing import TYPE_CHECKING
1013

1114
from invoke import Collection, task
1215

1316
from .gdb import gdb_build_cmd
1417

18+
if TYPE_CHECKING:
19+
from tasks.lib.invoke_utils import Context
20+
1521
TASKS_DIR = os.path.dirname(__file__)
1622
MEMFAULT_SDK_ROOT = os.path.join(TASKS_DIR, "..")
1723
ESP32_PLATFORM_ROOT = os.path.join(MEMFAULT_SDK_ROOT, "examples", "esp32")
@@ -25,7 +31,7 @@
2531
OPENOCD_GDB_PORT_DEFAULT = 3333
2632

2733

28-
def _run_idf_script(ctx, *args, **kwargs):
34+
def _run_idf_script(ctx: "Context", *args: str, **kwargs: object) -> None:
2935
# allow selecting a specific python interpreter instead of the active one.
3036
# this is necessary in CI, because the mbed build task modifies the python
3137
# environment 😖, and idf.py runs a pkg_resources.require() which fails if
@@ -52,7 +58,7 @@ def _run_idf_script(ctx, *args, **kwargs):
5258

5359

5460
@task
55-
def run_xtensa_toolchain_check(ctx):
61+
def run_xtensa_toolchain_check(ctx: "Context") -> None:
5662
if sys.version_info.major < 3:
5763
# shutil which is only available for python3
5864
return
@@ -70,19 +76,19 @@ def run_xtensa_toolchain_check(ctx):
7076

7177

7278
@task(pre=[run_xtensa_toolchain_check])
73-
def esp32_app_build(ctx):
79+
def esp32_app_build(ctx: "Context") -> None:
7480
"""Build the ESP32 test app"""
7581
_run_idf_script(ctx, "build")
7682

7783

7884
@task
79-
def esp32_app_clean(ctx):
85+
def esp32_app_clean(ctx: "Context") -> None:
8086
"""Clean the ESP32 test app"""
8187
_run_idf_script(ctx, "fullclean")
8288

8389

8490
@task(pre=[run_xtensa_toolchain_check])
85-
def esp32s2_app_build(ctx):
91+
def esp32s2_app_build(ctx: "Context") -> None:
8692
"""Build the ESP32-S2 test app"""
8793
# !NOTE! 'set-target' was added in ESP-IDF v4.1. If you are using an older
8894
# version of ESP-IDF, building for the ESP32-S2 + ESP32-S3 won't work.
@@ -91,32 +97,32 @@ def esp32s2_app_build(ctx):
9197

9298

9399
@task(pre=[run_xtensa_toolchain_check])
94-
def esp32s3_app_build(ctx):
100+
def esp32s3_app_build(ctx: "Context") -> None:
95101
"""Build the ESP32-S3 test app"""
96102
_run_idf_script(ctx, "set-target esp32s3")
97103
_run_idf_script(ctx, "build")
98104

99105

100106
@task
101-
def esp32_app_flash(ctx):
107+
def esp32_app_flash(ctx: "Context") -> None:
102108
"""Flash the ESP32 test app"""
103109
_run_idf_script(ctx, "flash")
104110

105111

106112
@task
107-
def esp32_console(ctx):
113+
def esp32_console(ctx: "Context") -> None:
108114
"""Flash the ESP32 test app"""
109115
_run_idf_script(ctx, "monitor")
110116

111117

112118
@task
113-
def esp32_app_menuconfig(ctx):
119+
def esp32_app_menuconfig(ctx: "Context") -> None:
114120
"""Run menuconfig for the ESP32 test app"""
115121
_run_idf_script(ctx, "menuconfig", pty=True)
116122

117123

118124
@task
119-
def esp32_openocd(ctx):
125+
def esp32_openocd(ctx: "Context") -> None:
120126
"""Launch openocd"""
121127
if "ESP32_OPENOCD" not in os.environ:
122128
print("Set ESP32_OPENOCD environment variable to point to openocd-esp32 root directory!")
@@ -134,7 +140,7 @@ def esp32_openocd(ctx):
134140

135141

136142
@task
137-
def esp32_app_gdb(ctx, gdb=None, reset=False):
143+
def esp32_app_gdb(ctx: "Context", gdb: int | None = None, reset: bool = False) -> None:
138144
"""Launches xtensa-gdb with app elf and connects to openocd gdb server"""
139145
if gdb is None:
140146
gdb = OPENOCD_GDB_PORT_DEFAULT
@@ -146,7 +152,9 @@ def esp32_app_gdb(ctx, gdb=None, reset=False):
146152

147153

148154
@task
149-
def esp32_decode_backtrace(ctx, backtrace_str, symbol_file, verbose=False):
155+
def esp32_decode_backtrace(
156+
ctx: "Context", backtrace_str: str, symbol_file: str, verbose: bool = False
157+
) -> None:
150158
"""Decode a backtrace emitted by ESP-IDF panic handling
151159
152160
The backtrace_str should be passed as a string of separated address pairs

tasks/gdb.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
# See LICENSE for details
44
#
55

6+
from __future__ import annotations
7+
68
try:
79
from shutil import which # Python 3
810
except ImportError: # Python 2
911
from distutils.spawn import find_executable as which
1012

1113

12-
def gdb_find(prefix=None):
14+
def gdb_find(prefix: str | None = None) -> str:
1315
if prefix is None:
1416
prefix = "arm-none-eabi-"
1517
base_name = "{}gdb".format(prefix)
@@ -21,7 +23,13 @@ def gdb_find(prefix=None):
2123
raise FileNotFoundError("Cannot find {}".format(" or ".join(ordered_names)))
2224

2325

24-
def gdb_build_cmd(extra_args, elf, gdb_port, reset=True, gdb_prefix=None):
26+
def gdb_build_cmd(
27+
extra_args: str | None,
28+
elf: str,
29+
gdb_port: int,
30+
reset: bool = True,
31+
gdb_prefix: str | None = None,
32+
) -> str:
2533
base_cmd = '{gdb} --eval-command="target remote localhost:{port}"'.format(
2634
gdb=gdb_find(gdb_prefix), port=gdb_port
2735
)

tasks/macos_ftdi.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,24 @@
33
# See LICENSE for details
44
#
55

6+
from __future__ import annotations
7+
8+
from collections.abc import Generator
69
from contextlib import contextmanager
710
from os import uname
11+
from typing import TYPE_CHECKING
12+
13+
if TYPE_CHECKING:
14+
from tasks.lib.invoke_utils import Context
815

916
APPLE_FTDI_DRIVER_BUNDLE_ID = "com.apple.driver.AppleUSBFTDI"
1017

1118

12-
def is_macos():
19+
def is_macos() -> bool:
1320
return uname()[0] == "Darwin"
1421

1522

16-
def _unload_apple_ftdi_driver_if_needed(ctx):
23+
def _unload_apple_ftdi_driver_if_needed(ctx: Context) -> bool | None:
1724
if not is_macos():
1825
return None
1926
result = ctx.run("kextstat -b {}".format(APPLE_FTDI_DRIVER_BUNDLE_ID), hide=True)
@@ -24,15 +31,15 @@ def _unload_apple_ftdi_driver_if_needed(ctx):
2431
return loaded
2532

2633

27-
def _load_apple_ftdi_driver_if_needed(ctx):
34+
def _load_apple_ftdi_driver_if_needed(ctx: Context) -> None:
2835
if not is_macos():
2936
return
3037
print("Re-loading Apple FTDI driver...")
3138
ctx.run("sudo kextload -b {}".format(APPLE_FTDI_DRIVER_BUNDLE_ID))
3239

3340

3441
@contextmanager
35-
def apple_ftdi_driver_disable(ctx):
42+
def apple_ftdi_driver_disable(ctx: Context) -> Generator[None, None, None]:
3643
was_ftdi_driver_loaded = _unload_apple_ftdi_driver_if_needed(ctx)
3744
try:
3845
yield

tasks/mbed.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33
# See LICENSE for details
44
#
55

6+
from __future__ import annotations
7+
68
import os
79
import shlex
810
import shutil
911
import sys
12+
from typing import TYPE_CHECKING
1013

1114
from invoke import Collection, task
1215

1316
from .print_chunk_watcher import PrintChunkWatcher
1417

18+
if TYPE_CHECKING:
19+
from tasks.lib.invoke_utils import Context
20+
1521
TASKS_DIR = os.path.dirname(__file__)
1622
MEMFAULT_SDK_ROOT = os.path.dirname(TASKS_DIR)
1723
MBED_TARGET = "DISCO_F429ZI"
@@ -29,7 +35,7 @@
2935

3036

3137
@task
32-
def mbed_clean(ctx):
38+
def mbed_clean(ctx: Context) -> None:
3339
"""Clean demo app that runs on Mbed OS 5"""
3440
print("Mbed CLI does not have a separate 'clean' action; approximating it...")
3541
if os.path.exists(MBED_DEMO_APP_BUILD_ROOT):
@@ -38,7 +44,7 @@ def mbed_clean(ctx):
3844

3945

4046
@task
41-
def mbed_update(ctx):
47+
def mbed_update(ctx: Context) -> None:
4248
"""Update or install the library dependencies for the Mbed demo app"""
4349
cmd = "mbed update"
4450
with ctx.cd(MBED_DEMO_APP_ROOT):
@@ -74,7 +80,7 @@ def mbed_update(ctx):
7480

7581

7682
@task
77-
def _mbed_update_required(ctx):
83+
def _mbed_update_required(ctx: Context) -> None:
7884
"""Most tasks require that the mbed_update task have been run at least once
7985
before to install mbed-os. Do it now if it has not been done yet."""
8086
mbed_dir = os.path.join(MBED_DEMO_APP_ROOT, "mbed-os")
@@ -93,12 +99,12 @@ def _mbed_update_required(ctx):
9399
},
94100
)
95101
def mbed_build(
96-
ctx,
97-
profile=MBED_DEMO_APP_BUILD_PROFILE,
98-
toolchain=MBED_TOOLCHAIN,
99-
target=MBED_TARGET,
100-
flash=False,
101-
):
102+
ctx: Context,
103+
profile: str = MBED_DEMO_APP_BUILD_PROFILE,
104+
toolchain: str = MBED_TOOLCHAIN,
105+
target: str = MBED_TARGET,
106+
flash: bool = False,
107+
) -> None:
102108
"""Build the demo app that runs on Mbed OS 5"""
103109
cmd = "mbed compile --profile {} --toolchain {} --target {}".format(
104110
shlex.quote(profile), shlex.quote(toolchain), shlex.quote(target)
@@ -124,7 +130,7 @@ def mbed_build(
124130
@task(
125131
pre=[_mbed_update_required], help={"target": "Mbed target name (def: {})".format(MBED_TARGET)}
126132
)
127-
def mbed_flash(ctx, target=MBED_TARGET):
133+
def mbed_flash(ctx: Context, target: str = MBED_TARGET) -> None:
128134
"""Flash (and first build) the demo app that runs on Mbed OS 5"""
129135
print("Mbed CLI does not have a separate 'flash' action; approximating it...")
130136
mbed_build(ctx, flash=True, target=target)
@@ -138,7 +144,7 @@ def mbed_flash(ctx, target=MBED_TARGET):
138144
"target": "Mbed target name (def: {})".format(MBED_TARGET),
139145
},
140146
)
141-
def mbed_console(ctx, baudrate=MBED_BAUD_RATE, target=MBED_TARGET):
147+
def mbed_console(ctx: Context, baudrate: int = MBED_BAUD_RATE, target: str = MBED_TARGET) -> None:
142148
"""Start an Mbed serial console to interact with the demo app"""
143149
cmd = "mbed sterm --baudrate {:d} --echo off --target {}".format(baudrate, shlex.quote(target))
144150
with ctx.cd(MBED_DEMO_APP_ROOT):

0 commit comments

Comments
 (0)