Skip to content

Commit

Permalink
Memfault Firmware SDK 1.16.0 (Build 10952)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Oct 24, 2024
1 parent 72f52c0 commit 7cc391d
Show file tree
Hide file tree
Showing 86 changed files with 635 additions and 1,946 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ coverage:
round: down
range: "70...100"
status:
patch: off
project:
default:
target: 70%
Expand Down
78 changes: 76 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,79 @@ 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.16.0] - 2024-10-24

### 🔥 Removed

- Removed support for Zephyr < 2.7.0
- Removed support for nRF-Connect SDK < 1.9.2
- Removed support for ESP-IDF < 4.4.0

Please [contact us](https://mflt.io/contact-support) if you need support for
earlier versions!

### 🐛 Fixed

- General:

- Correct an issue where `eMemfaultRebootReason` is expressed as a 4-byte type
instead of 2-bytes when compiling with Clang with high optimization, when
targeting ARM. This results in Coredumps tagged as `Unknown` instead of the
correct reason code.

### 📈 Added

- General:

- Add a pair of optional user-provided functions,
`memfault_reboot_tracking_load()` / `memfault_reboot_tracking_save()`, to
allow users to provide their own implementations for saving and loading
reboot tracking data. This is useful when the default implementation is not
suitable for the platform or when the user wants to store the data in a
different location.

- The
[Stable Sessions Device Vital](https://docs.memfault.com/docs/platform/memfault-core-metrics#stable-sessions)
added in SDK version `1.15.0` is fully available and no longer considered
experimental.

- Add an optional `memfault_port_coredump_save_begin()` callback, for use by
Memfault ports. This allows `memfault_platform_coredump_save_begin()` to be
implemented by the platform instead, for custom pre-coredump operations.
Thanks to @finger563 for reporting this issue in
[#77](https://github.com/memfault/memfault-firmware-sdk/issues/77)!

- Improved API docs for events and data packetizer components by noting
restrictions for use in ISR contexts

- Zephyr:

- Update the Qemu app to support the `nucleo_l496zg` board, with support for
the Zephyr `bbram` subsystem, and implement the new
`memfault_reboot_tracking_load()` / `memfault_reboot_tracking_save()`
functions to demonstrate the functionality.

- ESP-IDF:

- New Kconfig setting, `CONFIG_MEMFAULT_ENABLE_REBOOT_DIAG_DUMP`, to print the
ESP-IDF reboot reason code on system boot, for debugging purposes. This
feature is disabled by default.

### 🛠️ Changed

- General:

- Update support links to refer to the preferred site
<https://mflt.io/contact-support> instead of the Memfault support email.
This link will redirect to a form where questions can be sent to the
Memfault support team.

- nRF-Connect SDK:

- Changed the Kconfig symbol `MEMFAULT_REBOOT_REASON_GET_CUSTOM` to be `imply`
instead of `select` when the nRF-Connect SDK is enabled. This permits users
to disable the `nrfx`-based reboot reason tracking if needed.

## [1.15.0] - 2024-10-13

### 📈 Added
Expand Down Expand Up @@ -1361,8 +1434,9 @@ earlier versions!
- Improve FOTA support for nRF-Connect SDK 2.4+, by improving the technique
used to find the correct Memfault server root cert. Memfault uses a fast CDN
to improve OTA payload delivery, which uses a different root cert than the
Memfault device server. Please contact <[email protected]> immediately if
you encounter any cert-related issues.
Memfault device server. Please
[contact support](https://mflt.io/contact-support) immediately if you
encounter any cert-related issues.

### 💥 Breaking Changes

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: 10752
GIT COMMIT: 1904cdb3cb
VERSION: 1.15.0
BUILD ID: 10952
GIT COMMIT: c690f5abc6
VERSION: 1.16.0
12 changes: 12 additions & 0 deletions components/core/src/memfault_ram_reboot_info_tracking.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,23 @@ static void prv_record_reboot_event(eMemfaultRebootReason reboot_reason,
s_mflt_reboot_info->lr = reg->lr;
}

MEMFAULT_WEAK void memfault_reboot_tracking_load(sMemfaultRebootTrackingStorage *dst) {
(void)dst;
}

MEMFAULT_WEAK void memfault_reboot_tracking_save(const sMemfaultRebootTrackingStorage *src) {
(void)src;
}

void memfault_reboot_tracking_boot(void *start_addr, const sResetBootupInfo *bootup_info) {
s_mflt_reboot_info = start_addr;

if (start_addr == NULL) {
return;
}

memfault_reboot_tracking_load((sMemfaultRebootTrackingStorage *)s_mflt_reboot_info);

if (!prv_check_or_init_struct()) {
return;
}
Expand All @@ -191,6 +201,8 @@ void memfault_reboot_tracking_mark_reset_imminent(eMemfaultRebootReason reboot_r
}

prv_record_reboot_event(reboot_reason, reg);

memfault_reboot_tracking_save((const sMemfaultRebootTrackingStorage *)s_mflt_reboot_info);
}

bool memfault_reboot_tracking_read_reset_info(sMfltResetReasonInfo *info) {
Expand Down
17 changes: 13 additions & 4 deletions components/include/memfault/core/data_packetizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
extern "C" {
#endif

//! Fills buffer with a chunk when there is data available
//! Fill buffer with a chunk when there is data available
//!
//! NOTE: This is the simplest way to interact with the packetizer. The API call returns a single
//! "chunk" to be forwarded out over the transport topology to the Memfault cloud. For more
//! advanced control over chunking, the lower level APIs exposed below in this module can be used.
//! @note This function must not be called from an ISR context.
//!
//! @param[out] buf The buffer to copy data to be sent into
//! @param[in,out] buf_len The size of the buffer to copy data into. On return, populated
Expand Down Expand Up @@ -54,10 +55,13 @@ typedef enum {
//! transport path.
#define MEMFAULT_PACKETIZER_MIN_BUF_LEN 9

//! @return true if there is data available to send, false otherwise
//! Check if there is data available to send
//!
//! @note This can be used prior to opening a connection over the underlying transport to the
//! internet
//! @note This function must not be called from an ISR context.
//!
//! This can be used to check if there is any data to send prior to opening a connection over the
//! underlying transport to the internet
//! @return true if there is data available to send, false otherwise
bool memfault_packetizer_data_available(void);

typedef struct {
Expand Down Expand Up @@ -87,6 +91,10 @@ typedef struct {
uint32_t single_chunk_message_length;
} sPacketizerMetadata;

//! Initialize the packetizer and get metadata about the message to be sent
//!
//! @note This function must not be called from an ISR context.
//!
//! @return true if there is data available to send, false otherwise.
bool memfault_packetizer_begin(const sPacketizerConfig *cfg, sPacketizerMetadata *metadata_out);

Expand All @@ -106,6 +114,7 @@ bool memfault_packetizer_begin(const sPacketizerConfig *cfg, sPacketizerMetadata
//! this API up to the cloud _reliably_ and _in-order_.
//! @note The api is not threadsafe. The expectation is that a user will drain data from a single
//! thread or otherwise wrap the call with a mutex
//! @note This function must not be called from an ISR context.
//!
//! @param[out] buf The buffer to copy data to be sent into
//! @param[in,out] buf_len The size of the buffer to copy data into. On return, populated
Expand Down
17 changes: 13 additions & 4 deletions components/include/memfault/core/event_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,25 @@ int memfault_event_storage_persist(void);

#endif

//! Simple API call to retrieve the number of bytes used in the allocated event storage buffer.
//! Returns zero if the storage has not been allocated.
//! Retrieve the number of bytes used in the allocated event storage buffer.
//!
//! @note This function must not be called from an ISR context.
//!
//! @return zero if the storage has not been allocated.
size_t memfault_event_storage_bytes_used(void);

//! Simple API call to retrieve the number of bytes free (unused) in the allocated event storage
//! buffer. Returns zero if the storage has not been allocated.
//! Retrieve the number of bytes free (unused) in the allocated event storage
//! buffer.
//!
//! @note This function must not be called from an ISR context.
//!
//! @return zero if the storage has not been allocated.
size_t memfault_event_storage_bytes_free(void);

//! Check if event storage component has booted
//!
//! @note This function must not be called from an ISR context.
//!
//! @returns true if event storage booted or false if not
bool memfault_event_storage_booted(void);

Expand Down
6 changes: 5 additions & 1 deletion components/include/memfault/core/reboot_reason_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ extern "C" {
#undef MEMFAULT_EXPECTED_REBOOT_REASON_DEFINE
#undef MEMFAULT_UNEXPECTED_REBOOT_REASON_DEFINE

typedef enum MfltResetReason {
//! This enum must be packed to prevent compiler optimizations in instructions which load an
//! eMemfaultRebootReason.
typedef enum MEMFAULT_PACKED MfltResetReason {
// A reboot reason was not determined either by hardware or a previously marked reboot reason
// This reason is classified as a crash when calculating the operational_crashfree_hours metric
kMfltRebootReason_Unknown = 0x0000,
Expand Down Expand Up @@ -135,6 +137,8 @@ typedef enum MfltResetReason {

} eMemfaultRebootReason;

MEMFAULT_STATIC_ASSERT(sizeof(eMemfaultRebootReason) == 2, "Reboot reason enum must be 2 bytes");

#if MEMFAULT_REBOOT_REASON_CUSTOM_ENABLE == 1
// Ensure that the custom reboot reasons are within the expected range
#define MEMFAULT_EXPECTED_REBOOT_REASON_DEFINE(name) \
Expand Down
34 changes: 34 additions & 0 deletions components/include/memfault/core/reboot_tracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,40 @@ bool memfault_reboot_tracking_metrics_session_was_active(uint32_t index);
//! @param name The name of the custom reboot reason
#define MEMFAULT_REBOOT_REASON_KEY(name) kMfltRebootReason_##name

//! The below pair of functions, memfault_reboot_tracking_load and
//! memfault_reboot_tracking_save, are used when the reboot tracking RAM storage
//! cannot be safely persisted across reboots. In this case, the user can
//! provide their own implementation to load and save the reboot tracking data
//! to a backing store (e.g. battery-backed ram, non-memory-mapped backup
//! registers, etc).
//!
//! memfault_reboot_tracking_load() is called from
//! memfault_reboot_tracking_boot(), and is used to retrieve the initial value
//! of the reboot tracking data from the backing store.
//!
//! memfault_reboot_tracking_save() is called from
//! memfault_reboot_tracking_mark_reset_imminent(), and is used to persist the
//! reboot tracking data to the backing store.

typedef MEMFAULT_PACKED_STRUCT MemfaultRebootTrackingStorage {
uint8_t data[MEMFAULT_REBOOT_TRACKING_REGION_SIZE];
}
sMemfaultRebootTrackingStorage;

//! Optional callback issued to load reboot tracking from the backing store,
//! called during Memfault reboot tracking initialization.
//!
//! @param dst The destination buffer to load into
extern void memfault_reboot_tracking_load(sMemfaultRebootTrackingStorage *dst);

//! Optional callback issued when reboot tracking data should be saved to the
//! backing store, for persistence across reboots. This function MUST be safe
//! to call from exception context! It is called from the Memfault fault handler
//! before the coredump is saved.
//!
//! @param src The source buffer to save
extern void memfault_reboot_tracking_save(const sMemfaultRebootTrackingStorage *src);

#ifdef __cplusplus
}
#endif
8 changes: 8 additions & 0 deletions components/include/memfault/panics/platform/coredump.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ extern bool memfault_coredump_read(uint32_t offset, void *buf, size_t buf_len);
//! @return true if to continue saving the coredump, false to abort
extern bool memfault_platform_coredump_save_begin(void);

//! Called prior to invoking any platform_storage_[read/write/erase] calls upon
//! crash
//!
//! @note this is similar to memfault_platform_coredump_save_begin(), but is
//! meant to be implemented by the Memfault port, not the user platform
//! @return true if to continue saving the coredump, false to abort
extern bool memfault_port_coredump_save_begin(void);

#ifdef __cplusplus
}
#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 = 15, .patch = 0 }
#define MEMFAULT_SDK_VERSION_STR "1.15.0"
{ .major = 1, .minor = 16, .patch = 0 }
#define MEMFAULT_SDK_VERSION_STR "1.16.0"

#ifdef __cplusplus
}
Expand Down
6 changes: 5 additions & 1 deletion components/panics/src/memfault_coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ static bool prv_write_coredump_sections(const sMemfaultCoredumpSaveInfo *save_in
}

if (!compute_size_only) {
if (!memfault_platform_coredump_save_begin()) {
if (!memfault_port_coredump_save_begin() || !memfault_platform_coredump_save_begin()) {
return false;
}

Expand Down Expand Up @@ -529,6 +529,10 @@ MEMFAULT_WEAK bool memfault_platform_coredump_save_begin(void) {
return true;
}

MEMFAULT_WEAK bool memfault_port_coredump_save_begin(void) {
return true;
}

size_t memfault_coredump_get_save_size(const sMemfaultCoredumpSaveInfo *save_info) {
const bool compute_size_only = true;
size_t total_size = 0;
Expand Down
2 changes: 1 addition & 1 deletion components/panics/src/memfault_coredump_storage_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ bool memfault_coredump_storage_debug_test_begin(void) {
// On some ports there maybe some extra setup that needs to occur
// before we can safely use the backing store without interrupts
// enabled. Call this setup function now.
if (!memfault_platform_coredump_save_begin()) {
if (!memfault_port_coredump_save_begin() || !memfault_platform_coredump_save_begin()) {
prv_record_failure(kMemfaultCoredumpStorageTestOp_Prepare,
kMemfaultCoredumpStorageResult_PlatformApiFail, 0, info.size);
return false;
Expand Down
2 changes: 1 addition & 1 deletion components/panics/src/memfault_fault_handling_riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ MEMFAULT_NO_OPT void memfault_fault_handling_assert(void *pc, void *lr) {
}

#elif !defined(ESP_PLATFORM)
#error "Unsupported RISC-V platform, please contact [email protected]"
#error "Unsupported RISC-V platform. Please visit https://mflt.io/contact-support"
#endif // !defined(ESP_PLATFORM) && defined(__ZEPHYR__)

void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason reason) {
Expand Down
2 changes: 1 addition & 1 deletion components/panics/src/memfault_fault_handling_xtensa.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ MEMFAULT_NO_OPT void memfault_fault_handling_assert(void *pc, void *lr) {
}

#elif !defined(ESP_PLATFORM)
#error "Unsupported Xtensa platform, please contact [email protected]"
#error "Unsupported Xtensa platform. Please visit https://mflt.io/contact-support"
#endif // !defined(ESP_PLATFORM) && defined(__ZEPHYR__)

void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason reason) {
Expand Down
31 changes: 0 additions & 31 deletions examples/esp32/apps/memfault_demo_app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,34 +76,3 @@ if (INVALID_PARTITION_TABLE)
If this error occurs repeatedly run `idf.py fullclean && rm sdkconfig`"
)
endif()

if (CONFIG_MEMFAULT)
# Set MEMFAULT_IDF_VERSION, used for version-specific logic later.
if (IDF_VERSION_MAJOR)
set(MEMFAULT_IDF_VERSION "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}")
else()
# pre-4.0 doesn't have version information available to cmake, so set it to
# the lowest compatible version
set(MEMFAULT_IDF_VERSION "3.3.5")
endif()

# As of Memfault SDK v1.12.0, adding the Memfault Build ID is done in the
# memfault component for ESP-IDF >=4.2.5.
if(MEMFAULT_IDF_VERSION VERSION_LESS "4.2.5")
# Add the Memfault Build ID so each build can have a unique version.
set(IDF_PROJECT_EXECUTABLE ${PROJECT_NAME}.elf)
add_custom_command(TARGET ${IDF_PROJECT_EXECUTABLE}
POST_BUILD
# Compute and insert the build id
COMMAND python ${memfault_firmware_sdk_dir}/scripts/fw_build_id.py ${IDF_PROJECT_EXECUTABLE}
# Save a copy of the ELF that includes the 'log_fmt' section
BYPRODUCTS ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt
# Compress debug sections; this reduces the elf file size from ~10MB -> ~4.8MB
COMMAND ${CMAKE_OBJCOPY} --compress-debug-sections ${IDF_PROJECT_EXECUTABLE}
COMMAND ${CMAKE_COMMAND} -E copy ${IDF_PROJECT_EXECUTABLE} ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt
COMMAND ${CMAKE_COMMAND} -E echo "*** NOTE: the symbol file to upload to app.memfault.com is ${IDF_PROJECT_EXECUTABLE}.memfault_log_fmt ***"
# Remove the 'log_fmt' compact log section, which confuses elf2image
COMMAND ${CMAKE_OBJCOPY} --remove-section log_fmt ${IDF_PROJECT_EXECUTABLE}
)
endif()
endif() # NOT CONFIG_MEMFAULT_DISABLE
Loading

0 comments on commit 7cc391d

Please sign in to comment.