Skip to content

Commit

Permalink
Memfault Firmware SDK 1.1.3 (Build 3171)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Aug 8, 2023
1 parent 5d57753 commit bf7e954
Show file tree
Hide file tree
Showing 25 changed files with 421 additions and 105 deletions.
26 changes: 26 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
### Changes between Memfault SDK 1.1.2 and 1.1.3 - Aug 8, 2023

#### :chart_with_upwards_trend: Improvements

- Set Memfault SDK version in a string metric on device boot, for easier
tracking of SDK versions in the Memfault UI
- Support using a different identifier for the GNU build id symbol (previously
was fixed to `__start_gnu_build_id_start`). Use the
`MEMFAULT_GNU_BUILD_ID_SYMBOL` define in `memfault_platform_config.h` to
override the default. For Zephyr, the Kconfig option
`CONFIG_MEMFAULT_GNU_BUILD_ID_SOURCE_BUILTIN` can be used to override the
builtin section specifier + linker fragment for the GNU build ID. Thanks to
@JordanYates for posting this change in
[#60](https://github.com/memfault/memfault-firmware-sdk/pull/60) 🎉
- Improvements to the ARMv7-R exception handling when the supervisor processor
mode is active

- Zephyr:
- Add an optional mode to create and open the HTTP socket in separate function
calls, if the user needs to set additional socket options before connecting.
See
[ports/zephyr/include/memfault/ports/zephyr/http.h](ports/zephyr/include/memfault/ports/zephyr/http.h)
for details. Fixes
[#52](https://github.com/memfault/memfault-firmware-sdk/issues/52)- thanks
to @anicare-tero for posting this 🎉

### Changes between Memfault SDK 1.1.1 and 1.1.2 - July 11, 2023

#### :chart_with_upwards_trend: Improvements
Expand Down
4 changes: 2 additions & 2 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
BUILD ID: 2861
GIT COMMIT: 3a1297110
BUILD ID: 3171
GIT COMMIT: cd928ad15
4 changes: 2 additions & 2 deletions components/core/src/memfault_build_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
#if MEMFAULT_USE_GNU_BUILD_ID

// Note: This variable is emitted by the linker script
extern uint8_t __start_gnu_build_id_start[];
extern uint8_t MEMFAULT_GNU_BUILD_ID_SYMBOL[];

MEMFAULT_BUILD_ID_QUALIFIER sMemfaultBuildIdStorage g_memfault_build_id = {
.type = kMemfaultBuildIdType_GnuBuildIdSha1,
.len = sizeof(sMemfaultElfNoteSection),
.short_len = MEMFAULT_EVENT_INCLUDED_BUILD_ID_SIZE_BYTES,
.storage = __start_gnu_build_id_start,
.storage = MEMFAULT_GNU_BUILD_ID_SYMBOL,
.sdk_version = MEMFAULT_SDK_VERSION,
};
#else
Expand Down
17 changes: 14 additions & 3 deletions components/core/src/memfault_heap_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,30 @@ static uint16_t prv_get_previous_entry(uint16_t search_entry_index) {

//! Return the next entry index to write new data to
//!
//! First searches for unused entries
//! If none are found then traverses list to oldest (last) entry
//! First searches for never-used entries, then unused (used + freed) entries.
//! If none are found then traverses list to oldest (last) entry.
static uint16_t prv_get_new_entry_index(void) {
sMfltHeapStatEntry *entry;
uint16_t unused_index = MEMFAULT_HEAP_STATS_LIST_END;

for (uint16_t i = 0; i < MEMFAULT_ARRAY_SIZE(g_memfault_heap_stats_pool); i++) {
entry = &g_memfault_heap_stats_pool[i];

if (!entry->info.in_use) {
return i; // favor unused entries
if (entry->info.size == 0) {
return i; // favor never used entries
}
// save the first inactive entry found
if (unused_index == MEMFAULT_HEAP_STATS_LIST_END) {
unused_index = i;
}
}
}

if (unused_index != MEMFAULT_HEAP_STATS_LIST_END) {
return unused_index;
}

// No unused entry found, return the oldest (entry with next index of
// MEMFAULT_HEAP_STATS_LIST_END)
return prv_get_previous_entry(MEMFAULT_HEAP_STATS_LIST_END);
Expand Down
1 change: 1 addition & 0 deletions components/include/memfault/components.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern "C" {
#include "memfault/util/crc16_ccitt.h"
#include "memfault/util/rle.h"
#include "memfault/util/varint.h"
#include "memfault/version.h"

#ifdef __cplusplus
}
Expand Down
5 changes: 5 additions & 0 deletions components/include/memfault/default_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ extern "C" {
#define MEMFAULT_USE_GNU_BUILD_ID 0
#endif

//! Controls the name used to reference the GNU build ID data
#ifndef MEMFAULT_GNU_BUILD_ID_SYMBOL
#define MEMFAULT_GNU_BUILD_ID_SYMBOL __start_gnu_build_id_start
#endif

//! Allows users to dial in the correct amount of storage for their
//! software version + build ID string.
#ifndef MEMFAULT_UNIQUE_VERSION_MAX_LEN
Expand Down
3 changes: 3 additions & 0 deletions components/include/memfault/metrics/heartbeat_config.def
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//! default health statistics for the fleet. All other metrics are provided by the user
//! of the sdk via the MEMFAULT_METRICS_USER_HEARTBEAT_DEFS_FILE file

// Memfault SDK Version String
#include "memfault/version.h"
MEMFAULT_METRICS_STRING_KEY_DEFINE(MemfaultSdkMetric_sdk_version, sizeof(MEMFAULT_SDK_VERSION_STR) - 1)
// The time since the last heartbeat was collected in ms
MEMFAULT_METRICS_KEY_DEFINE(MemfaultSdkMetric_IntervalMs, kMemfaultMetricType_Timer)
// The number of reboots that have taken place since the last heartbeat was collected
Expand Down
3 changes: 2 additions & 1 deletion components/include/memfault/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ typedef struct {
uint8_t patch;
} sMfltSdkVersion;

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

#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 @@ -897,6 +897,9 @@ int memfault_metrics_boot(const sMemfaultEventStorageImpl *storage_impl,
return rv;
}

rv = memfault_metrics_heartbeat_set_string(MEMFAULT_METRICS_KEY(MemfaultSdkMetric_sdk_version),
MEMFAULT_SDK_VERSION_STR);

rv = prv_init_unexpected_reboot_metric();
if (rv != 0) {
return rv;
Expand Down
28 changes: 27 additions & 1 deletion components/panics/src/memfault_fault_handling_armv7_a_r.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bool memfault_arch_is_inside_isr(void) {
// Reference Manual section "B1.3.1 ARM processor modes" for these values.
#define CPSR_MODE_msk 0x1f
#define CPSR_USER_msk 0x10
#define CPSR_SUPERVISOR_msk 0x13
#define CPSR_SYSTEM_msk 0x1f

uint32_t cpsr;
Expand All @@ -84,8 +85,9 @@ bool memfault_arch_is_inside_isr(void) {

const bool in_user_mode = (mode == CPSR_USER_msk);
const bool in_system_mode = (mode == CPSR_SYSTEM_msk);
const bool in_supervisor_mode = (mode == CPSR_SUPERVISOR_msk);

return !(in_user_mode || in_system_mode);
return !(in_user_mode || in_system_mode || in_supervisor_mode);
}

#if defined(__GNUC__)
Expand Down Expand Up @@ -237,6 +239,9 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
// Processor mode values, used when saving LR and SPSR to the appropriate stack.
// From https://developer.arm.com/documentation/dui0801/a/CHDEDCCD
// Defined as strings for macro concatenation below
#define CPU_MODE_FIQ_STR "0x11"
#define CPU_MODE_IRQ_STR "0x12"
#define CPU_MODE_SUPERVISOR_STR "0x13"
#define CPU_MODE_ABORT_STR "0x17"
#define CPU_MODE_UNDEFINED_STR "0x1b"
#define CPU_MODE_SYSTEM_STR "0x1f"
Expand Down Expand Up @@ -281,7 +286,28 @@ void memfault_fault_handler(const sMfltRegState *regs, eMemfaultRebootReason rea
/* push user mode regs at point of fault, including sp + lr */ \
"mov r8, r1 \n" \
"mov r1, sp \n" \
/* Save SPSR and mask mode bits */ \
"mrs r9, spsr \n" \
"and r9, #0x1f \n" \
/* Check each applicable mode and set current mode on a match */ \
"cmp r9, #" CPU_MODE_IRQ_STR " \n" \
"bne fiq_mode_%= \n" \
"cps #" CPU_MODE_IRQ_STR " \n" \
"b store_regs_%= \n" \
"fiq_mode_%=: \n" \
"cmp r9, #" CPU_MODE_FIQ_STR " \n" \
"bne supervisor_mode_%= \n" \
"cps #" CPU_MODE_FIQ_STR " \n" \
"b store_regs_%= \n" \
"supervisor_mode_%=: \n" \
"cmp r9, #" CPU_MODE_SUPERVISOR_STR " \n" \
"bne system_mode_%= \n" \
"cps #" CPU_MODE_SUPERVISOR_STR " \n" \
"b store_regs_%= \n" \
/* Fall back to system mode if no match */ \
"system_mode_%=: \n" \
"cps #" CPU_MODE_SYSTEM_STR " \n" \
"store_regs_%=: \n" \
"stmfd r1!, {r8-r12, sp, lr} \n"\
"cps #" _mode_string" \n" \
/* save active registers in exception frame */ \
Expand Down
17 changes: 14 additions & 3 deletions examples/esp32/apps/memfault_demo_app/main/console_example_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ static void prv_memfault_ota(void) {
MEMFAULT_LOG_INFO("Update available!");
} else if (rv < 0) {
MEMFAULT_LOG_ERROR("OTA update failed, rv=%d", rv);

// record a Trace Event when this happens, and freeze the log buffer to be
// uploaded for diagnosis
MEMFAULT_TRACE_EVENT_WITH_LOG(ota_install_failure, "error code=%d", rv);
memfault_log_trigger_collection();

led_set_color(kLedColor_Red);
}
}
Expand Down Expand Up @@ -202,6 +208,8 @@ void memfault_esp_port_wifi_autojoin(void) {
static void prv_poster_task(void *args) {
const uint32_t interval_sec = 60;
const TickType_t delay_ms = (1000 * interval_sec) / portTICK_PERIOD_MS;
const TickType_t ota_check_interval = pdMS_TO_TICKS(60 * 60 * 1000);
TickType_t ota_last_check_time = xTaskGetTickCount() - ota_check_interval;

MEMFAULT_LOG_INFO("Data poster task up and running every %" PRIu32 "s.", interval_sec);

Expand All @@ -218,10 +226,13 @@ static void prv_poster_task(void *args) {
// if the check-in succeeded, set green, otherwise clear.
// gives a quick eyeball check that the app is alive and well
led_set_color((err == 0) ? kLedColor_Green : kLedColor_Red);
}

// check for OTA update
prv_memfault_ota();
// Check for OTA hourly
if ((xTaskGetTickCount() - ota_last_check_time) >= ota_check_interval) {
prv_memfault_ota();
ota_last_check_time = xTaskGetTickCount();
}
}

// sleep
vTaskDelay(delay_ms);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// File for holding custom error traces:
// https://mflt.io/error-tracing
// https://mflt.io/error-tracing
MEMFAULT_TRACE_REASON_DEFINE(ota_install_failure)
29 changes: 29 additions & 0 deletions ports/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,35 @@ config MEMFAULT_CATCH_ZEPHYR_ASSERT
from __ASSERT() macro call sites, unless assert_post_action() contains
a MEMFAULT_ASSERT() invocation.

menuconfig MEMFAULT_USE_GNU_BUILD_ID
default y
bool "Use a GNU build ID in an image"

if MEMFAULT_USE_GNU_BUILD_ID

choice MEMFAULT_GNU_BUILD_ID_SOURCE
prompt "GNU Build ID source"
default MEMFAULT_GNU_BUILD_ID_SOURCE_BUILTIN
help
Choose if a GNU build ID is generated by built-in SDK features
or by other means

config MEMFAULT_GNU_BUILD_ID_SOURCE_BUILTIN
bool "Built-in via Memfault SDK"
help
Use the Memfault SDK to generate and include a GNU build ID

config MEMFAULT_GNU_BUILD_ID_SOURCE_CUSTOM
bool "Custom source"
help
Use a custom source to generate and include a GNU build ID
Set the name of the GNU build ID symbol with MEMFAULT_GNU_BUILD_ID_SYMBOL
in your application's memfault_platform_config.h

endchoice # MEMFAULT_GNU_BUILD_ID_SOURCE

endif # MEMFAULT_USE_GNU_BUILD_ID

module = MEMFAULT
module-str = Memfault
source "subsys/logging/Kconfig.template.log_config"
Expand Down
11 changes: 6 additions & 5 deletions ports/zephyr/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ zephyr_library_sources_ifdef(CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD memfault_http_
# by placing them in special linker sections
zephyr_linker_sources(NOINIT memfault-no-init.ld)

zephyr_linker_sources(SECTIONS memfault-build-id.ld)

# Override the default Zephyr setting which disables the GNU Build ID
# https://github.com/zephyrproject-rtos/zephyr/blob/d7ee114106eab485688223d97a49813d33b4cf21/cmake/linker/ld/target_base.cmake#L16
zephyr_ld_options("-Wl,--build-id")
if (CONFIG_MEMFAULT_GNU_BUILD_ID_SOURCE_BUILTIN)
zephyr_linker_sources(SECTIONS memfault-build-id.ld)
# Override the default Zephyr setting which disables the GNU Build ID
# https://github.com/zephyrproject-rtos/zephyr/blob/d7ee114106eab485688223d97a49813d33b4cf21/cmake/linker/ld/target_base.cmake#L16
zephyr_ld_options("-Wl,--build-id")
endif()

if(CONFIG_MEMFAULT_HEAP_STATS AND CONFIG_HEAP_MEM_POOL_SIZE GREATER 0)
zephyr_ld_options(-Wl,--wrap=k_malloc)
Expand Down
Loading

0 comments on commit bf7e954

Please sign in to comment.