Skip to content

Commit

Permalink
Memfault Firmware SDK 1.18.0 (Build 11548)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Nov 25, 2024
1 parent 053865f commit 0bd360f
Show file tree
Hide file tree
Showing 20 changed files with 253 additions and 108 deletions.
37 changes: 31 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@ 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.18.0] - 2024-11-25

### 📈 Added

- General:

- Add a new built-in metric, `uptime_s`, which reports the total uptime of the
device in seconds. This metrics is enabled by default, and can be disabled
with `#define MEMFAULT_METRICS_UPTIME_ENABLE 0` in
`memfault_platform_config.h`.

- Zephyr:

- Update the [QEMU sample app](examples/zephyr/qemu) to use newly-released
Zephyr v4.0.0 🥳.

- ESP-IDF:

- Added support for dual-core coredumps on ESP32 and ESP32-S3. This feature is
enabled by default and can be disabled with the Kconfig option
`CONFIG_MEMFAULT_COREDUMP_CPU_COUNT=1`. Note: not all fault conditions will
cause both CPU cores to be captured in the coredump. The SDK will always
capture the core that triggered the fault, and if the non-faulting core is
available for capture, it will be included as well.

## [1.17.0] - 2024-11-14

### 📈 Added
Expand Down Expand Up @@ -43,16 +68,16 @@ and this project adheres to
# Before:
mflt> test_log
Raw log!
2024-11-14T17:01:12Z|4284 I Info log!
2024-11-14T17:01:12Z|4284 W Warning log!
2024-11-14T17:01:12Z|4284 E Error log!
MFLT:[INFO] Info log!
MFLT:[WARN] Warning log!
MFLT:[ERRO] Error log!

# After:
mflt> test_log
Raw log!
MFLT:[INFO] Info log!
MFLT:[WARN] Warning log!
MFLT:[ERRO] Error log!
2024-11-14T17:01:12Z|4284 I Info log!
2024-11-14T17:01:12Z|4284 W Warning log!
2024-11-14T17:01:12Z|4284 E Error log!
```

- ESP-IDF:
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: 11353
GIT COMMIT: 767ed66f9e
VERSION: 1.17.0
BUILD ID: 11548
GIT COMMIT: 045729d525
VERSION: 1.18.0
12 changes: 12 additions & 0 deletions components/include/memfault/default_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ extern "C" {
#define MEMFAULT_COREDUMP_INCLUDE_BUILD_ID 1
#endif

//! Some architectures will support multiple cores. This is used by the
//! architecture-specific coredump handling code to determine how many
//! register sets to save.
#ifndef MEMFAULT_COREDUMP_CPU_COUNT
#define MEMFAULT_COREDUMP_CPU_COUNT 1
#endif

//! Controls the truncation of the Build Id that is encoded in events
//!
//! The full Build Id hash is 20 bytes, but is truncated by default to save space. The
Expand Down Expand Up @@ -347,6 +354,11 @@ extern "C" {
#define MEMFAULT_METRICS_LOGS_ENABLE 1
#endif

//! Enable built in uptime metric tracking
#ifndef MEMFAULT_METRICS_UPTIME_ENABLE
#define MEMFAULT_METRICS_UPTIME_ENABLE 1
#endif

//! Disable Metrics Sessions at compile time. This saves a small amount of
//! memory but prevents the use of Metrics Sessions.
#ifndef MEMFAULT_METRICS_SESSIONS_ENABLED
Expand Down
4 changes: 4 additions & 0 deletions components/include/memfault/metrics/heartbeat_config.def
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ MEMFAULT_METRICS_KEY_DEFINE_WITH_SCALE_VALUE(battery_soc_pct, kMemfaultMetricTyp
MEMFAULT_METRICS_KEY_DEFINE(MemfaultSDKMetric_log_dropped_lines, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_KEY_DEFINE(MemfaultSDKMetric_log_recorded_lines, kMemfaultMetricType_Unsigned)
#endif

#if MEMFAULT_METRICS_UPTIME_ENABLE
MEMFAULT_METRICS_KEY_DEFINE(uptime_s, kMemfaultMetricType_Unsigned)
#endif
4 changes: 2 additions & 2 deletions components/include/memfault/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ typedef struct {
} sMfltSdkVersion;

#define MEMFAULT_SDK_VERSION \
{ .major = 1, .minor = 17, .patch = 0 }
#define MEMFAULT_SDK_VERSION_STR "1.17.0"
{ .major = 1, .minor = 18, .patch = 0 }
#define MEMFAULT_SDK_VERSION_STR "1.18.0"

#ifdef __cplusplus
}
Expand Down
3 changes: 3 additions & 0 deletions components/metrics/src/memfault_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,9 @@ static void prv_collect_builtin_data(void) {
#if MEMFAULT_METRICS_LOGS_ENABLE
prv_memfault_collect_log_metrics();
#endif
#if MEMFAULT_METRICS_UPTIME_ENABLE
MEMFAULT_METRIC_SET_UNSIGNED(uptime_s, memfault_platform_get_time_since_boot_ms() / 1000);
#endif
}

// Returns NULL if not a timer type or out of bounds index.
Expand Down
14 changes: 14 additions & 0 deletions components/panics/src/memfault_coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,24 @@ static bool prv_write_coredump_sections(const sMemfaultCoredumpSaveInfo *save_in
const void *regs = save_info->regs;
const size_t regs_size = save_info->regs_size;
if (regs != NULL) {
#if MEMFAULT_COREDUMP_CPU_COUNT == 1
if (!prv_write_non_memory_block(kMfltCoredumpBlockType_CurrentRegisters, regs, regs_size,
&write_ctx)) {
return false;
}
#else
// If we have multiple CPUs, we need to save the registers for each CPU.
// save_info->regs is an array of CPU0, CPU1, etc. registers.
for (size_t i = 0; i < MEMFAULT_COREDUMP_CPU_COUNT; i++) {
const size_t cpu_regs_size = regs_size / MEMFAULT_COREDUMP_CPU_COUNT;
const uint32_t *cpu_regs = (const uint32_t *)((const uintptr_t)regs + (i * cpu_regs_size));

if (!prv_write_non_memory_block(kMfltCoredumpBlockType_CurrentRegisters, cpu_regs,
cpu_regs_size, &write_ctx)) {
return false;
}
}
#endif
}

if (!prv_write_device_info_blocks(&write_ctx)) {
Expand Down
27 changes: 23 additions & 4 deletions components/panics/src/memfault_fault_handling_xtensa.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,34 @@ MEMFAULT_NO_OPT void memfault_fault_handling_assert(void *pc, void *lr) {
#error "Unsupported Xtensa platform. Please visit https://mflt.io/contact-support"
#endif // !defined(ESP_PLATFORM) && defined(__ZEPHYR__)

#if MEMFAULT_COREDUMP_CPU_COUNT > 1
#if defined(__ZEPHYR__)
#error "Dual-core support not yet implemented for Zephyr Xtensa"
#else
#include "esp_cpu.h"

#endif

static int prv_get_current_cpu_id(void) {
return esp_cpu_get_core_id();
}
#endif // MEMFAULT_COREDUMP_CPU_COUNT == 1

void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason reason) {
#if MEMFAULT_COREDUMP_CPU_COUNT == 1
const sMfltRegState *current_cpu_regs = regs;
#else
const int cpu_id = prv_get_current_cpu_id();
const sMfltRegState *current_cpu_regs = &regs[cpu_id];
#endif
if (s_crash_reason == kMfltRebootReason_Unknown) {
// skip LR saving here.
prv_fault_handling_assert((void *)regs->pc, (void *)0, reason);
prv_fault_handling_assert((void *)current_cpu_regs->pc, (void *)0, reason);
}

sMemfaultCoredumpSaveInfo save_info = {
.regs = regs,
.regs_size = sizeof(*regs),
.regs_size = sizeof(*regs) * MEMFAULT_COREDUMP_CPU_COUNT,
.trace_reason = s_crash_reason,
};

Expand All @@ -122,7 +141,7 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
// For the windowed ABI, a1 always holds the current "sp":
// https://github.com/espressif/esp-idf/blob/v4.0/components/freertos/readme_xtensa.txt#L421-L428
const uint32_t windowed_abi_spill_size = 64;
const uint32_t sp_prior_to_exception = regs->a[1] - windowed_abi_spill_size;
const uint32_t sp_prior_to_exception = current_cpu_regs->a[1] - windowed_abi_spill_size;

sCoredumpCrashInfo info = {
.stack_address = (void *)sp_prior_to_exception,
Expand All @@ -139,7 +158,7 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea

size_t memfault_coredump_storage_compute_size_required(void) {
// actual values don't matter since we are just computing the size
sMfltRegState core_regs = { 0 };
sMfltRegState core_regs[MEMFAULT_COREDUMP_CPU_COUNT] = { 0 };
sMemfaultCoredumpSaveInfo save_info = {
.regs = &core_regs,
.regs_size = sizeof(core_regs),
Expand Down
2 changes: 1 addition & 1 deletion examples/zephyr/qemu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ the following commands to test the application:
❯ west build qemu-app
❯ west build --target run

*** Booting Zephyr OS build zephyr-v3.2.0 ***
*** Booting Zephyr OS build zephyr-v4.0.0 ***
[00:00:00.000,000] <inf> mflt: GNU Build ID: 4ffb5879ed5923582035133086015bbf65504364
[00:00:00.000,000] <inf> main: 👋 Memfault Demo App! Board qemu_cortex_m3

Expand Down
2 changes: 1 addition & 1 deletion examples/zephyr/qemu/qemu-app/west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ manifest:
projects:
- name: zephyr
remote: zephyrproject-rtos
revision: v3.7.0
revision: v4.0.0
import:
# Limit the Zephyr modules to the required set
name-allowlist:
Expand Down
11 changes: 11 additions & 0 deletions ports/esp_idf/memfault/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ endif
'memfault_platform_coredump_storage_get_info()' function to return
the threshold value set here as the size of the partition..

config MEMFAULT_COREDUMP_CPU_COUNT
int "Number of CPU cores to include in coredumps"
default SOC_CPU_CORES_NUM
# Symbolic values in the range are not supported by
# confgen.py/esp-idf-kconfig until later versions (esp-idf 5+). Hard
# code to a max of 2.
range 1 2
help
The number of CPU cores to include in coredumps. By default, all
cores are included.

config MEMFAULT_AUTOMATIC_INIT
bool "[DEPRECATED] Automatically initialize the SDK when the system is booted"
default n
Expand Down
Loading

0 comments on commit 0bd360f

Please sign in to comment.