Skip to content

Commit 47d69c5

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 1.12.0 (Build 10351)
1 parent 00ff70f commit 47d69c5

File tree

27 files changed

+747
-198
lines changed

27 files changed

+747
-198
lines changed

CHANGELOG.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,75 @@ 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.12.0] - 2024-09-25
10+
11+
### 📈 Added
12+
13+
- ESP-IDF:
14+
15+
- The SDK now supports being installed as an
16+
[ESP Component](https://components.espressif.com/) from the Espressif
17+
registry, by adding the following lines to an esp-idf project's
18+
`idf_component.yml` manifest:
19+
20+
```yaml
21+
dependencies:
22+
memfault/memfault-firmware-sdk:
23+
version: "1.12.0"
24+
```
25+
26+
- [Heap Allocation Tracking](https://docs.memfault.com/docs/mcu/heap-stats) is
27+
now enabled by default for ESP-IDF projects, controlled with the Kconfig
28+
symbol `CONFIG_MEMFAULT_HEAP_STATS`. The Memfault Trace UI will show
29+
information about the most recent heap allocations for `malloc()` calls.
30+
31+
### 🛠️ Changed
32+
33+
- ESP-IDF:
34+
35+
- The [Memfault Build ID](https://mflt.io/symbol-file-build-ids) will be
36+
applied by default, controlled by the Kconfig setting
37+
`CONFIG_MEMFAULT_USE_MEMFAULT_BUILD_ID`. This is _only_ valid for ESP-IDF
38+
versions >= **4.2.5** , and will cause a build error on older versions,
39+
requiring it to be set to `n`. Updating to this version of the SDK will
40+
**require** removing the similar logic in the project's `CMakeLists.txt`
41+
file (a build error will occur if both are present).
42+
43+
- The Memfault Core Vital for
44+
[Periodic Connectivity](https://docs.memfault.com/docs/platform/memfault-core-metrics#periodic-connectivity)
45+
will now count failures to sync Memfault data if the HTTP connection cannot
46+
be established, but WiFi connectivity is available. This can occur when the
47+
WAN connection is down but the access point is still up, or if there is an
48+
external DNS failure. Previously this was not counted as a failure.
49+
50+
- Zephyr
51+
52+
- The Memfault HTTP client, enabled with Kconfig
53+
`CONFIG_MEMFAULT_HTTP_ENABLE`, requires `POSIX_API` to be enabled on newer
54+
versions of Zephyr. Previously, not explicitly enabling `POSIX_API` would
55+
result in a build error. Update it to be enabled by default in the Zephyr
56+
SDK, via Kconfig `imply POSIX_API`.
57+
58+
- Zephyr 3.7.0+ requires enabling `CONFIG_MBEDTLS_SHA1` when using Zephyr's
59+
mbedtls implementation. Memfault added a build-time check for this setting
60+
in Memfault SDK 1.11.2, but that check would also trip when not using
61+
Zephyr's mbedtls implementation. Update the build check to be more precise.
62+
63+
- nRF-Connect SDK:
64+
65+
- Minor changes to provide compatibility with NCS versions > 2.7.0, which
66+
target a Zephyr fork that is compatible with 3.7.0 but provides a
67+
"development" version number, 3.6.99.
68+
69+
### 🐛 Fixed
70+
71+
- ESP-IDF:
72+
73+
- Corrected a theoretical integer overflow issue in the demo CLI `crash`
74+
command, detected by static analysis tools. The impacted function was and is
75+
exclusively called with an argument of `10`, so this issue was not
76+
exploitable in practice.
77+
978
## [1.11.5] - 2024-09-18
1079

1180
### 📈 Added

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.12.4)
2+
3+
if(ESP_PLATFORM)
4+
include(${CMAKE_CURRENT_LIST_DIR}/ports/esp_idf/memfault/CMakeLists.txt)
5+
else()
6+
include(${CMAKE_CURRENT_LIST_DIR}/cmake/Memfault.cmake)
7+
endif()

Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# If the repo is being used as an ESP-IDF component, bring in the ESP-IDF specific
2+
# Kconfig file. Otherwise this should be unused.
3+
if IDF_TARGET != ""
4+
rsource "ports/esp_idf/memfault/Kconfig"
5+
endif

VERSION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
BUILD ID: 10200
2-
GIT COMMIT: 432492ab6b
3-
VERSION: 1.11.5
1+
BUILD ID: 10351
2+
GIT COMMIT: 1d3c51cd48
3+
VERSION: 1.12.0

components/core/src/memfault_heap_stats.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
MEMFAULT_STATIC_ASSERT(MEMFAULT_HEAP_STATS_MAX_COUNT < MEMFAULT_HEAP_STATS_LIST_END,
2828
"Number of entries in heap stats exceeds limits");
2929

30+
// By default, tally in use blocks and max in use blocks in the instrumentation
31+
// functions. Disable this to perform manual tallying.
32+
#if !defined(MEMFAULT_IN_USE_BLOCK_COUNT_AUTOMATIC)
33+
#define MEMFAULT_IN_USE_BLOCK_COUNT_AUTOMATIC 1
34+
#endif
35+
3036
sMfltHeapStats g_memfault_heap_stats = {
3137
.version = MEMFAULT_HEAP_STATS_VERSION,
3238
.stats_pool_head = MEMFAULT_HEAP_STATS_LIST_END,
@@ -111,14 +117,23 @@ static uint16_t prv_get_new_entry_index(void) {
111117
return prv_get_previous_entry(MEMFAULT_HEAP_STATS_LIST_END);
112118
}
113119

120+
void memfault_heap_stats_increment_in_use_block_count(void) {
121+
g_memfault_heap_stats.in_use_block_count++;
122+
if (g_memfault_heap_stats.in_use_block_count > g_memfault_heap_stats.max_in_use_block_count) {
123+
g_memfault_heap_stats.max_in_use_block_count = g_memfault_heap_stats.in_use_block_count;
124+
}
125+
}
126+
void memfault_heap_stats_decrement_in_use_block_count(void) {
127+
g_memfault_heap_stats.in_use_block_count--;
128+
}
129+
114130
void memfault_heap_stats_malloc(const void *lr, const void *ptr, size_t size) {
115131
prv_heap_stats_lock();
116132

117133
if (ptr) {
118-
g_memfault_heap_stats.in_use_block_count++;
119-
if (g_memfault_heap_stats.in_use_block_count > g_memfault_heap_stats.max_in_use_block_count) {
120-
g_memfault_heap_stats.max_in_use_block_count = g_memfault_heap_stats.in_use_block_count;
121-
}
134+
#if MEMFAULT_IN_USE_BLOCK_COUNT_AUTOMATIC
135+
memfault_heap_stats_increment_in_use_block_count();
136+
#endif
122137
uint16_t new_entry_index = prv_get_new_entry_index();
123138

124139
// Ensure a valid entry index is returned. An invalid index can indicate a concurrency
@@ -156,7 +171,9 @@ void memfault_heap_stats_malloc(const void *lr, const void *ptr, size_t size) {
156171
void memfault_heap_stats_free(const void *ptr) {
157172
prv_heap_stats_lock();
158173
if (ptr) {
159-
g_memfault_heap_stats.in_use_block_count--;
174+
#if MEMFAULT_IN_USE_BLOCK_COUNT_AUTOMATIC
175+
memfault_heap_stats_decrement_in_use_block_count();
176+
#endif
160177

161178
// if the pointer exists in the tracked stats, mark it as freed
162179
for (size_t i = 0; i < MEMFAULT_ARRAY_SIZE(g_memfault_heap_stats_pool); i++) {

components/include/memfault/core/heap_stats.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ void memfault_heap_stats_free(const void *ptr);
8181

8282
#define MEMFAULT_HEAP_STATS_FREE(ptr_) memfault_heap_stats_free(ptr_)
8383

84+
//! These functions can be used to manually increment and decrement the
85+
//! in_use_block_count. This is useful if the application has custom memory
86+
//! tracing that provides more detailed information than just malloc/free.
87+
void memfault_heap_stats_decrement_in_use_block_count(void);
88+
void memfault_heap_stats_increment_in_use_block_count(void);
89+
8490
#ifdef __cplusplus
8591
}
8692
#endif

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 = 11, .patch = 5 }
24-
#define MEMFAULT_SDK_VERSION_STR "1.11.5"
23+
{ .major = 1, .minor = 12, .patch = 0 }
24+
#define MEMFAULT_SDK_VERSION_STR "1.12.0"
2525

2626
#ifdef __cplusplus
2727
}

examples/esp32/apps/memfault_demo_app/CMakeLists.txt

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,26 @@ if(DEFINED IDF_VERSION_MAJOR)
1515
endif()
1616
endif()
1717

18-
# Look for the Memfault SDK in a subdirectory first, when this app is used
19-
# standalone (not from within the Memfault SDK)
20-
get_filename_component(memfault_firmware_sdk_dir third-party/memfault-firmware-sdk ABSOLUTE)
21-
if(NOT EXISTS ${memfault_firmware_sdk_dir})
2218
get_filename_component(memfault_firmware_sdk_dir ../../../../ ABSOLUTE)
19+
# If we found the Memfault SDK, include it in the build
20+
if(EXISTS ${memfault_firmware_sdk_dir}/ports/esp_idf/memfault.cmake)
21+
include(${memfault_firmware_sdk_dir}/ports/esp_idf/memfault.cmake)
22+
else()
23+
# Otherwise, append this to the main/idf_component.yml file:
24+
# memfault/memfault-firmware-sdk: "*"
25+
# Ideally we'd push an environment variable and use a conditional dependency
26+
# https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/manifest_file.html#conditional-dependencies
27+
# But that requires idf-component-manager v2+, which is not available on all
28+
# esp-idf versions
29+
30+
# if the string "memfault/memfault-firmware-sdk" isn't in the file, append it:
31+
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/main/idf_component.yml idf_component_yml)
32+
if(NOT idf_component_yml MATCHES "memfault/memfault-firmware-sdk")
33+
file(APPEND ${CMAKE_CURRENT_SOURCE_DIR}/main/idf_component.yml
34+
" memfault/memfault-firmware-sdk: \"*\"\n"
35+
)
36+
endif()
2337
endif()
24-
include(${memfault_firmware_sdk_dir}/ports/esp_idf/memfault.cmake)
2538

2639
# NOTE: This include also applies global compiler options, make sure
2740
# this happens first before defining other targets!
@@ -65,19 +78,32 @@ if (INVALID_PARTITION_TABLE)
6578
endif()
6679

6780
if (CONFIG_MEMFAULT)
68-
# Add the Memfault Build ID so each build can have a unique version.
69-
set(IDF_PROJECT_EXECUTABLE ${PROJECT_NAME}.elf)
70-
add_custom_command(TARGET ${IDF_PROJECT_EXECUTABLE}
71-
POST_BUILD
72-
# Compute and insert the build id
73-
COMMAND python ${memfault_firmware_sdk_dir}/scripts/fw_build_id.py ${IDF_PROJECT_EXECUTABLE}
74-
# Save a copy of the ELF that includes the 'log_fmt' section
75-
BYPRODUCTS ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt
76-
# Compress debug sections; this reduces the elf file size from ~10MB -> ~4.8MB
77-
COMMAND ${CMAKE_OBJCOPY} --compress-debug-sections ${IDF_PROJECT_EXECUTABLE}
78-
COMMAND ${CMAKE_COMMAND} -E copy ${IDF_PROJECT_EXECUTABLE} ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt
79-
COMMAND ${CMAKE_COMMAND} -E echo "*** NOTE: the symbol file to upload to app.memfault.com is ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt ***"
80-
# Remove the 'log_fmt' compact log section, which confuses elf2image
81-
COMMAND ${CMAKE_OBJCOPY} --remove-section log_fmt ${IDF_PROJECT_EXECUTABLE}
82-
)
81+
# Set MEMFAULT_IDF_VERSION, used for version-specific logic later.
82+
if (IDF_VERSION_MAJOR)
83+
set(MEMFAULT_IDF_VERSION "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}")
84+
else()
85+
# pre-4.0 doesn't have version information available to cmake, so set it to
86+
# the lowest compatible version
87+
set(MEMFAULT_IDF_VERSION "3.3.5")
88+
endif()
89+
90+
# As of Memfault SDK v1.12.0, adding the Memfault Build ID is done in the
91+
# memfault component for ESP-IDF >=4.2.5.
92+
if(MEMFAULT_IDF_VERSION VERSION_LESS "4.2.5")
93+
# Add the Memfault Build ID so each build can have a unique version.
94+
set(IDF_PROJECT_EXECUTABLE ${PROJECT_NAME}.elf)
95+
add_custom_command(TARGET ${IDF_PROJECT_EXECUTABLE}
96+
POST_BUILD
97+
# Compute and insert the build id
98+
COMMAND python ${memfault_firmware_sdk_dir}/scripts/fw_build_id.py ${IDF_PROJECT_EXECUTABLE}
99+
# Save a copy of the ELF that includes the 'log_fmt' section
100+
BYPRODUCTS ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt
101+
# Compress debug sections; this reduces the elf file size from ~10MB -> ~4.8MB
102+
COMMAND ${CMAKE_OBJCOPY} --compress-debug-sections ${IDF_PROJECT_EXECUTABLE}
103+
COMMAND ${CMAKE_COMMAND} -E copy ${IDF_PROJECT_EXECUTABLE} ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt
104+
COMMAND ${CMAKE_COMMAND} -E echo "*** NOTE: the symbol file to upload to app.memfault.com is ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt ***"
105+
# Remove the 'log_fmt' compact log section, which confuses elf2image
106+
COMMAND ${CMAKE_OBJCOPY} --remove-section log_fmt ${IDF_PROJECT_EXECUTABLE}
107+
)
108+
endif()
83109
endif() # NOT CONFIG_MEMFAULT_DISABLE

examples/esp32/apps/memfault_demo_app/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ You can either follow the steps outlined here or use your own MQTT setup.
2121

2222
### Service Setup
2323

24-
1. Modify the script found in Docs->Best Practices->MQTT with Memfault with the the following:
24+
1. Modify the script found in [Docs->Best Practices->MQTT](https://docs.memfault.com/docs/best-practices/mqtt-with-memfault#service-examples)
25+
with Memfault with the the following:
2526
1. The service client login information previously created
2627
2. Connection info for your local broker
2728
3. Map of Memfault projects to project keys

examples/esp32/apps/memfault_demo_app/main/Kconfig.projbuild

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ config MEMFAULT_APP_WIFI_AUTOJOIN
2424
help
2525
Automatically join if credentials are configured.
2626

27+
config MEMFAULT_APP_HEAP_TRACING
28+
bool "Print allocation tracing information at runtime"
29+
default n
30+
depends on HEAP_USE_HOOKS
31+
2732
choice APP_MEMFAULT_TRANSPORT
2833
prompt "Protocol to send chunks over"
2934
default APP_MEMFAULT_TRANSPORT_HTTP

0 commit comments

Comments
 (0)