Skip to content

Commit

Permalink
Memfault Firmware SDK 1.11.3 (Build local)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc. committed Sep 5, 2024
1 parent 65447c9 commit 57cf611
Show file tree
Hide file tree
Showing 19 changed files with 211 additions and 31 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.11.3] - 2024-09-05

### :chart_with_upwards_trend: Improvements

- General:

- Improve assert stack unwinding for Clang builds when `-flto` is enabled.

- Zephyr:

- Add a new Kconfig option, `CONFIG_MEMFAULT_SOC_FAMILY_ESP32`, to resolve an
error when referencing the deprecated `CONFIG_SOC_FAMILY_ESP32` Kconfig
(removed in
[Zephyr 3.7.0](https://github.com/zephyrproject-rtos/zephyr/commit/8dc3f856229ce083c956aa301c31a23e65bd8cd8)
as part of Hardware Model V2). This new option is used in the Memfault
Zephyr port to check if an ESP32 SOC is being used.

- Remove references to the deprecated `BOOTLOADER_ESP_IDF` Kconfig symbol in
the Memfault Zephyr port (removed in Zephyr 3.7.0).

## [1.11.2] - 2024-08-29

### :chart_with_upwards_trend: Improvements
Expand Down
6 changes: 3 additions & 3 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
BUILD ID: 9770
GIT COMMIT: ea6fadf472
VERSION: 1.11.2
BUILD ID: local
GIT COMMIT: c29972dd3ef
VERSION: 1.11.3
9 changes: 8 additions & 1 deletion components/core/src/memfault_heap_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "memfault/core/math.h"
#include "memfault/core/platform/debug_log.h"
#include "memfault/core/platform/overrides.h"
#include "memfault/core/sdk_assert.h"

#define MEMFAULT_HEAP_STATS_VERSION 2

Expand Down Expand Up @@ -119,6 +120,12 @@ void memfault_heap_stats_malloc(const void *lr, const void *ptr, size_t size) {
g_memfault_heap_stats.max_in_use_block_count = g_memfault_heap_stats.in_use_block_count;
}
uint16_t new_entry_index = prv_get_new_entry_index();

// Ensure a valid entry index is returned. An invalid index can indicate a concurrency
// misconfiguration. MEMFAULT_HEAP_STATS_MALLOC/FREE must prevent concurrent access via
// memfault_lock/unlock or other means
MEMFAULT_SDK_ASSERT(new_entry_index != MEMFAULT_HEAP_STATS_LIST_END);

sMfltHeapStatEntry *new_entry = &g_memfault_heap_stats_pool[new_entry_index];
*new_entry = (sMfltHeapStatEntry){
.lr = lr,
Expand Down Expand Up @@ -165,7 +172,7 @@ void memfault_heap_stats_free(const void *ptr) {
g_memfault_heap_stats.stats_pool_head = entry->info.next_entry_index;
}

// If there's a valid previous entry, set it's next index to removed entry's
// If there's a valid previous entry, set its next index to removed entry's
if (previous_entry_index != MEMFAULT_HEAP_STATS_LIST_END) {
g_memfault_heap_stats_pool[previous_entry_index].info.next_entry_index =
entry->info.next_entry_index;
Expand Down
22 changes: 21 additions & 1 deletion components/core/src/memfault_ram_reboot_info_tracking.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@

#define MEMFAULT_REBOOT_INFO_VERSION 2

// clang-format off
// Internal value used to initialize sMfltRebootInfo.last_reboot_reason. Care must be taken when
// comparing this value to eMemfaultRebootReason as different platforms produce different behavior
// comparing uint32_t to enum types. In general, cast this value to the type it is compared against.
// Examples:
//
// uint32_t last_reboot_reason != MEMFAULT_REBOOT_REASON_NOT_SET (GOOD)
// eMemfaultRebootReason reboot_reason != (eMemfaultRebootReason)MEMFAULT_REBOOT_REASON_NOT_SET (GOOD)
// uint32_t last_reboot_reason != (eMemfaultRebootReason)MEMFAULT_REBOOT_REASON_NOT_SET (BAD)
// clang-format on
#define MEMFAULT_REBOOT_REASON_NOT_SET 0xffffffff

typedef MEMFAULT_PACKED_STRUCT MfltRebootInfo {
Expand Down Expand Up @@ -56,6 +66,10 @@ sMfltRebootInfo;
MEMFAULT_STATIC_ASSERT(sizeof(sMfltRebootInfo) == MEMFAULT_REBOOT_TRACKING_REGION_SIZE,
"struct doesn't match expected size");

MEMFAULT_STATIC_ASSERT(sizeof(eMemfaultRebootReason) <=
sizeof(((sMfltRebootInfo){ 0 }).last_reboot_reason),
"enum does not fit within sMfltRebootInfo.last_reboot_reason");

static sMfltRebootInfo *s_mflt_reboot_info;

//! Struct to retrieve reboot reason data from. Matches the fields of sMfltRebootReason
Expand Down Expand Up @@ -90,6 +104,7 @@ static bool prv_check_or_init_struct(void) {
}

static bool prv_read_reset_info(sMfltResetReasonInfo *info) {
// prior_stored_reason is a uint32_t, no need to cast MEMFAULT_REBOOT_REASON_NOT_SET
if ((s_mflt_reboot_info->last_reboot_reason == MEMFAULT_REBOOT_REASON_NOT_SET) &&
(s_mflt_reboot_info->reset_reason_reg0 == 0)) {
return false; // no reset crashes!
Expand Down Expand Up @@ -118,7 +133,8 @@ static void prv_record_reboot_reason(eMemfaultRebootReason reboot_reg_reason,
uint32_t prior_stored_reason) {
s_reboot_reason_data.reboot_reg_reason = reboot_reg_reason;

if (prior_stored_reason != (eMemfaultRebootReason)MEMFAULT_REBOOT_REASON_NOT_SET) {
// prior_stored_reason is a uint32_t, no need to cast MEMFAULT_REBOOT_REASON_NOT_SET
if (prior_stored_reason != MEMFAULT_REBOOT_REASON_NOT_SET) {
s_reboot_reason_data.prior_stored_reason = (eMemfaultRebootReason)prior_stored_reason;
} else {
s_reboot_reason_data.prior_stored_reason = reboot_reg_reason;
Expand All @@ -131,6 +147,9 @@ static bool prv_get_unexpected_reboot_occurred(void) {
// Use prior_stored_reason as source of reboot reason. Fallback to reboot_reg_reason if
// prior_stored_reason is not set
eMemfaultRebootReason reboot_reason;

// s_reboot_reason_data.prior_stored_reason is an eMemfaultRebootReason type, cast
// MEMFAULT_REBOOT_REASON_NOT_SET
if (s_reboot_reason_data.prior_stored_reason !=
(eMemfaultRebootReason)MEMFAULT_REBOOT_REASON_NOT_SET) {
reboot_reason = s_reboot_reason_data.prior_stored_reason;
Expand All @@ -151,6 +170,7 @@ static void prv_record_reboot_event(eMemfaultRebootReason reboot_reason,
// s_mflt_reboot_info can be cleared by any call to memfault_reboot_tracking_collect_reset_info
prv_record_reboot_reason(reboot_reason, s_mflt_reboot_info->last_reboot_reason);

// last_reboot_reason is a uint32_t, no need to cast MEMFAULT_REBOOT_REASON_NOT_SET
if (s_mflt_reboot_info->last_reboot_reason != MEMFAULT_REBOOT_REASON_NOT_SET) {
// we are already tracking a reboot. We don't overwrite this because generally the first reboot
// in a loop reveals what started the crash loop
Expand Down
3 changes: 0 additions & 3 deletions components/include/memfault/core/reboot_tracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@ typedef struct MfltRebootType {
eMemfaultRebootReason prior_stored_reason;
} sMfltRebootReason;

//! Value used to determine state of reboot tracking data
#define MEMFAULT_REBOOT_REASON_NOT_SET 0xffffffff

#define MEMFAULT_REBOOT_TRACKING_REGION_SIZE 64

//! Sets the memory region used for reboot tracking.
Expand Down
14 changes: 8 additions & 6 deletions components/include/memfault/panics/fault_handling.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ MEMFAULT_NAKED_FUNC void MEMFAULT_EXC_HANDLER_WATCHDOG(void);
//! @param lr The return address
//! @see MEMFAULT_ASSERT_RECORD
//! @see MEMFAULT_ASSERT
#if defined(__CC_ARM) || defined(__ICCARM__) || (defined(__clang__) && defined(__ti__))
//! ARMCC, IAR, and tiarmclang will optimize away link register stores from callsites which makes it
//! impossible for a reliable backtrace to be resolved so we don't use the NORETURN attribute
#if defined(__CC_ARM) || defined(__ICCARM__) || defined(__clang__)
//! ARMCC, IAR, and clang (include tiarmclang) will optimize away link register stores from
//! callsites which makes it impossible for a reliable backtrace to be resolved so we don't use the
//! NORETURN attribute
#else
MEMFAULT_NORETURN
#endif
Expand All @@ -97,9 +98,10 @@ void memfault_fault_handling_assert(void *pc, void *lr);
//! @param extra_info Additional information used by the assert handler
//! @see MEMFAULT_ASSERT_RECORD
//! @see MEMFAULT_ASSERT
#if defined(__CC_ARM) || defined(__ICCARM__) || (defined(__clang__) && defined(__ti__))
//! ARMCC, IAR, and tiarmclang optimize away link register stores from callsites which makes it
//! impossible for a reliable backtrace to be resolved so we don't use the NORETURN attribute
#if defined(__CC_ARM) || defined(__ICCARM__) || defined(__clang__)
//! ARMCC, IAR, and clang (include tiarmclang) will optimize away link register stores from
//! callsites which makes it impossible for a reliable backtrace to be resolved so we don't use the
//! NORETURN attribute
#else
MEMFAULT_NORETURN
#endif
Expand Down
4 changes: 2 additions & 2 deletions components/include/memfault/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ typedef struct {
uint8_t patch;
} sMfltSdkVersion;

#define MEMFAULT_SDK_VERSION { .major = 1, .minor = 11, .patch = 2 }
#define MEMFAULT_SDK_VERSION_STR "1.11.2"
#define MEMFAULT_SDK_VERSION { .major = 1, .minor = 11, .patch = 3 }
#define MEMFAULT_SDK_VERSION_STR "1.11.3"

#ifdef __cplusplus
}
Expand Down
8 changes: 7 additions & 1 deletion components/panics/src/memfault_fault_handling_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,13 @@ void MEMFAULT_ASSERT_TRAP(void) {
#define MEMFAULT_ASSERT_TRAP() __asm volatile("udf #77")
#endif

static void prv_fault_handling_assert(void *pc, void *lr, eMemfaultRebootReason reason) {
#if defined(__clang__)
// When using clang with LTO, the compiler can optimize storing the LR + FP from this function,
// disable optimizations to fix
MEMFAULT_NO_OPT
#endif
static void
prv_fault_handling_assert(void *pc, void *lr, eMemfaultRebootReason reason) {
// Only set the crash reason if it's unset, in case we are in a nested assert
if (s_crash_reason == kMfltRebootReason_Unknown) {
sMfltRebootTrackingRegInfo info = {
Expand Down
3 changes: 1 addition & 2 deletions components/panics/src/memfault_fault_handling_riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ void memfault_arch_fault_handling_assert(void *pc, void *lr, eMemfaultRebootReas

// For non-esp-idf riscv implementations, provide a full assert handler and
// other utilities.
#if defined(__ZEPHYR__) && \
(defined(CONFIG_SOC_FAMILY_ESP32) || defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32))
#if defined(__ZEPHYR__) && (defined(CONFIG_MEMFAULT_SOC_FAMILY_ESP32))
#include <hal/cpu_hal.h>
#include <zephyr/kernel.h>

Expand Down
3 changes: 1 addition & 2 deletions components/panics/src/memfault_fault_handling_xtensa.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ void memfault_arch_fault_handling_assert(void *pc, void *lr, eMemfaultRebootReas

// For Zephyr Xtensa, provide an assert handler and other utilities.
// The Kconfig for the ESP32 family changed in v3.7.0. Support both Kconfigs
#if defined(__ZEPHYR__) && \
(defined(CONFIG_SOC_FAMILY_ESP32) || defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32))
#if defined(__ZEPHYR__) && (defined(CONFIG_MEMFAULT_SOC_FAMILY_ESP32))
#include <hal/cpu_hal.h>
#include <zephyr/kernel.h>

Expand Down
4 changes: 4 additions & 0 deletions components/panics/src/memfault_stdlib_assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ void __assert_func(const char *file, int line, const char *func, const char *fai
(void)file, (void)line, (void)func, (void)failedexpr;
#endif
MEMFAULT_ASSERT(0);

#if defined(__clang__)
MEMFAULT_UNREACHABLE;
#endif
}

#endif // MEMFAULT_ASSERT_CSTDLIB_HOOK_ENABLED && !defined(__TI_ARM__)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
extern "C" {
#endif

#if defined(CONFIG_SOC_FAMILY_ESP32) || defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32)
#if defined(CONFIG_MEMFAULT_SOC_FAMILY_ESP32)
#define ZEPHYR_DATA_REGION_START _data_start
#define ZEPHYR_DATA_REGION_END _data_end
#endif
Expand Down
22 changes: 17 additions & 5 deletions ports/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ if MEMFAULT
config MEMFAULT_CACHE_FAULT_REGS
bool "Memfault Cache ARM fault registers"
default y
depends on CPU_CORTEX_M
help
Save a copy of the ARMv7's fault registers before Zephyr
modifies them to provide a more accurate crash analysis
Expand All @@ -40,6 +41,17 @@ config MEMFAULT_USER_CONFIG_SILENT_FAIL
memfault_metrics_heartbeat_config.def
memfault_trace_reason_user_config.def

config MEMFAULT_SOC_FAMILY_ESP32
bool "Enable ESP32 support"
# Note: the generic ESP32 family config changed from SOC_FAMILY_ESP32 to
# SOC_FAMILY_ESPRESSIF_ESP32 in Zephyr 3.7.0. To provide backwards
# compatible support without referencing unavailable Kconfig values,
# generate a Memfault-specific option that works on Zephyr 3.7.0 and
# also earlier releases.
default y if SOC_FAMILY_ESPRESSIF_ESP32 || SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3
help
Enable ESP32 support in the Memfault SDK

# sub menu for coredump settings
menu "Memfault Coredump Settings"

Expand Down Expand Up @@ -148,7 +160,7 @@ endmenu # Memfault Coredump Settings
config MEMFAULT_HEAP_STATS
bool "Collect system heap stats with coredumps"
# our wrapper conflicts with the esp32 heap_caps implementation
default y if (!SOC_FAMILY_ESP32 && !SOC_FAMILY_ESPRESSIF_ESP32)
default y if (!MEMFAULT_SOC_FAMILY_ESP32)
select SYS_HEAP_RUNTIME_STATS
depends on HEAP_MEM_POOL_SIZE > 0
help
Expand Down Expand Up @@ -417,7 +429,7 @@ config MEMFAULT_REBOOT_REASON_GET_CUSTOM

config MEMFAULT_REBOOT_TRACKING_REGION
string "Memfault Reboot Tracking Region"
default ".rtc_noinit" if (SOC_FAMILY_ESP32 || SOC_FAMILY_ESPRESSIF_ESP32)
default ".rtc_noinit" if (MEMFAULT_SOC_FAMILY_ESP32)
default ".noinit.mflt_reboot_info"
help
The region in memory where the reboot tracking information will be stored.
Expand Down Expand Up @@ -657,8 +669,8 @@ config MEMFAULT_CDR_ENABLE

choice MEMFAULT_BUILD_ID_TYPE
prompt "Build ID type"
default MEMFAULT_USE_GNU_BUILD_ID if !BOOTLOADER_ESP_IDF
default MEMFAULT_USE_MEMFAULT_BUILD_ID if BOOTLOADER_ESP_IDF
default MEMFAULT_USE_MEMFAULT_BUILD_ID if (MEMFAULT_SOC_FAMILY_ESP32 && !BOOTLOADER_MCUBOOT)
default MEMFAULT_USE_GNU_BUILD_ID
help
Choose the type of build ID to include in the image

Expand All @@ -672,7 +684,7 @@ config MEMFAULT_USE_MEMFAULT_BUILD_ID

menuconfig MEMFAULT_USE_GNU_BUILD_ID
bool "Use a GNU build ID in an image"
depends on !BOOTLOADER_ESP_IDF
depends on !(MEMFAULT_SOC_FAMILY_ESP32 && !BOOTLOADER_MCUBOOT)

if MEMFAULT_USE_GNU_BUILD_ID

Expand Down
2 changes: 1 addition & 1 deletion ports/zephyr/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ if(CONFIG_MEMFAULT_HEAP_STATS AND CONFIG_HEAP_MEM_POOL_SIZE GREATER 0)
zephyr_ld_options(-Wl,--wrap=k_free)
endif()

if(CONFIG_SOC_FAMILY_ESP32 OR CONFIG_SOC_FAMILY_ESPRESSIF_ESP32)
if(CONFIG_MEMFAULT_SOC_FAMILY_ESP32)
zephyr_linker_sources(SECTIONS memfault-rtc-noinit-region.ld)
endif()

Expand Down
2 changes: 1 addition & 1 deletion ports/zephyr/common/memfault-build-id.ld
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SECTION_PROLOGUE(.note.gnu.build-id,,)
* GROUP_DATA_LINK_IN() is newer to Zephyr so it may not catch all cases;
* #ifdef on the ESP32 family for now.
*/
#if defined(CONFIG_SOC_FAMILY_ESP32) || defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32)
#if defined(CONFIG_MEMFAULT_SOC_FAMILY_ESP32)
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
#else
} GROUP_LINK_IN(ROMABLE_REGION)
Expand Down
2 changes: 1 addition & 1 deletion ports/zephyr/common/memfault_platform_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include "memfault/ports/zephyr/root_cert_storage.h"
#include "memfault/ports/zephyr/deprecated_root_cert.h"

#if MEMFAULT_ZEPHYR_VERSION_GT(3, 6)
#if MEMFAULT_ZEPHYR_VERSION_GT_STRICT(3, 6)

//! Zephyr 3.7.0 deprecated NET_SOCKETS_POSIX_NAMES, and requires POSIX_API to be enabled instead.
//! Confirm it's set.
Expand Down
2 changes: 2 additions & 0 deletions tests/MakefileWorkerOverrides.mk
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ COMPILER_SPECIFIC_WARNINGS += \
-Wno-zero-length-array \
-Wno-unsafe-buffer-usage \
-Wno-cast-function-type-strict \
-Wc23-extensions \

else
# GCC-only warnings
COMPILER_SPECIFIC_WARNINGS += \
-Wformat-signedness \
-fno-extended-identifiers \
-Wbidi-chars \
-Wc11-c2x-compat \

# Only enable -fanalyzer if GCC version is >= 12
GCC_VERSION_GTEQ_12 := $(shell expr $$($(CC) -dumpversion | cut -f1 -d.) \>= 12)
Expand Down
3 changes: 2 additions & 1 deletion tests/makefiles/Makefile_memfault_heap_stats.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ SRC_FILES = \
$(MFLT_COMPONENTS_DIR)/core/src/memfault_heap_stats.c

MOCK_AND_FAKE_SRC_FILES += \
$(MFLT_TEST_FAKE_DIR)/fake_memfault_platform_locking.c
$(MFLT_TEST_FAKE_DIR)/fake_memfault_platform_locking.c \
$(MFLT_TEST_FAKE_DIR)/fake_memfault_sdk_assert.c

TEST_SRC_FILES = \
$(MFLT_TEST_SRC_DIR)/test_memfault_heap_stats.cpp \
Expand Down
Loading

0 comments on commit 57cf611

Please sign in to comment.