Skip to content

Commit

Permalink
Memfault Firmware SDK 0.34.1 (Build 390)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Nov 7, 2022
1 parent 315d643 commit ac6cb05
Show file tree
Hide file tree
Showing 18 changed files with 243 additions and 23 deletions.
18 changes: 18 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
### Changes between Memfault SDK 0.34.1 and SDK 0.34.0 - Nov 7, 2022

#### :chart_with_upwards_trend: Improvements

- nRF-Connect:
- Updates for Zephyr upmerge 2022.11.03 (see #35 + #36)
- Fix watchdog test (`mflt test hang`) in
[`examples/nrf-connect-sdk/nrf5/`](examples/nrf-connect-sdk/nrf5/)
- Zephyr:
- Set `CONFIG_QEMU_ICOUNT=n` in
[`examples/zephyr/qemu/`](examples/zephyr/qemu/), which fixes the emulated
target execution speed
- Add heap free and stack usage Metrics to
[`examples/zephyr/qemu/`](examples/zephyr/qemu/)
- Update the `memfault_demo_cli_cmd_assert()` test command to take a single arg,
which is used in `MEMFAULT_ASSERT_RECORD()`. This enables testing that assert
variant from the CLI.

### Changes between Memfault SDK 0.34.0 and SDK 0.33.5 - Nov 1, 2022

#### :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: 320
GIT COMMIT: 0b70734d8
BUILD ID: 390
GIT COMMIT: d0c8fd2a6
9 changes: 7 additions & 2 deletions components/demo/src/panics/memfault_demo_panics.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,13 @@ int memfault_demo_cli_cmd_clear_core(MEMFAULT_UNUSED int argc, MEMFAULT_UNUSED c
return 0;
}

int memfault_demo_cli_cmd_assert(MEMFAULT_UNUSED int argc, MEMFAULT_UNUSED char *argv[]) {
MEMFAULT_ASSERT(0);
int memfault_demo_cli_cmd_assert(int argc, char *argv[]) {
// permit running with a user-provided "extra" value for testing that path
if (argc > 1) {
MEMFAULT_ASSERT_RECORD(atoi(argv[1]));
} else {
MEMFAULT_ASSERT(0);
}
}

#if MEMFAULT_COMPILER_ARM
Expand Down
2 changes: 1 addition & 1 deletion components/include/memfault/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ typedef struct {
uint8_t patch;
} sMfltSdkVersion;

#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 34, .patch = 0 }
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 34, .patch = 1 }

#ifdef __cplusplus
}
Expand Down
4 changes: 2 additions & 2 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ CONFIG_HWINFO=y

# Enable Memfault
CONFIG_MEMFAULT=y
# Below config is set by default in Memfault SDK 0.30.5+
CONFIG_MEMFAULT_NRF_CONNECT_SDK=y

# Use internal flash to store the coredump
CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP=y
Expand All @@ -36,6 +34,8 @@ CONFIG_SHELL_LOG_BACKEND=n
# Immediate logging is more performant at the expense of the rest of the system.
# Default is deferred to the logging thread.
CONFIG_LOG_MODE_IMMEDIATE=y
# Enable DBG log level
CONFIG_MEMFAULT_LOG_LEVEL_DBG=y

# Enable capture of recent logs as part of a coredump
CONFIG_MEMFAULT_LOGGING_ENABLE=y
Expand Down
33 changes: 33 additions & 0 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <memfault_ncs.h>
#include <stdio.h>

#include "memfault/ports/watchdog.h"

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

//! wrapper to enclose logic around log_strdup
Expand Down Expand Up @@ -51,11 +53,42 @@ static void prv_set_device_id(void) {
memfault_ncs_device_id_set(dev_str, length * 2);
}

#define WD_FEED_THREAD_STACK_SIZE 500
// set priority to lowest application thread; shell_uart, where the 'mflt test
// hang' command runs from, uses the same priority by default, so this should
// not preempt it and correctly trip the watchdog
#if CONFIG_SHELL_THREAD_PRIORITY_OVERRIDE
#error "Watchdog feed thread priority must be lower than shell thread priority"
#endif
#define WD_FEED_THREAD_PRIORITY K_LOWEST_APPLICATION_THREAD_PRIO

static void prv_wd_feed_thread_function(void *arg0, void *arg1, void *arg2) {
ARG_UNUSED(arg0);
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);

while (1) {
memfault_software_watchdog_feed();
k_sleep(K_SECONDS(1));
}
}
K_THREAD_DEFINE(wd_feed_thread, WD_FEED_THREAD_STACK_SIZE, prv_wd_feed_thread_function, NULL, NULL,
NULL, WD_FEED_THREAD_PRIORITY, 0, 0);

static void prv_start_watchdog_feed_thread(void) {
LOG_INF("starting watchdog feed thread 🐶");
memfault_software_watchdog_enable();
k_thread_name_set(wd_feed_thread, "wd_feed_thread");
k_thread_start(wd_feed_thread);
}

void main(void) {
LOG_INF("Booting Memfault sample app!");

// Set the device id based on the hardware UID
prv_set_device_id();

memfault_device_info_dump();

prv_start_watchdog_feed_thread();
}
20 changes: 11 additions & 9 deletions examples/nrf-connect-sdk/nrf9160/.gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
bootloader*
mbedtls*
modules*
nrf*
nrfxlib*
sdk-nrf*
test*
tools*
zephyr*
/bootloader
/build
/mbedtls
/modules
/nrf
/nrfxlib
/sparc
/test
/tools
/.west
/zephyr
13 changes: 7 additions & 6 deletions examples/zephyr/qemu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ the following commands to test the application:
❯ west update

# build the target program
# highly recommend '-DCONFIG_QEMU_ICOUNT=n' otherwise the guest runs too fast
❯ west build -b qemu_cortex_m3 --pristine=always zephyr-memfault-example/app -- -DCONFIG_QEMU_ICOUNT=n
❯ west build -b qemu_cortex_m3 --pristine=always qemu-app
❯ west build -t run

*** Booting Zephyr OS build zephyr-v3.1.0 ***
[00:00:00.000,000] <inf> mflt: GNU Build ID: a3f2f5da83bc62ceb0351f88a8b30d5cdab59ae9
[00:00:00.000,000] <inf> main: Memfault Demo App! Board qemu_cortex_m3
*** Booting Zephyr OS build zephyr-v3.2.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

[00:00:00.000,000] <inf> mflt: S/N: DEMOSERIAL
[00:00:00.000,000] <inf> mflt: SW type: zephyr-app
[00:00:00.000,000] <inf> mflt: SW version: 1.0.0-dev
[00:00:00.000,000] <inf> mflt: SW version: 1.0.0+6c108c40f1
[00:00:00.000,000] <inf> mflt: HW version: qemu_cortex_m3

uart:~$
```
1 change: 1 addition & 0 deletions examples/zephyr/qemu/qemu-app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

target_sources(app PRIVATE src/main.c)
zephyr_include_directories(config)
project(qemu-app LANGUAGES C VERSION 1.0.0)

# Generate a git hash that's used as part of the software_version, eg
Expand Down
6 changes: 6 additions & 0 deletions examples/zephyr/qemu/qemu-app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ config ZEPHYR_MEMFAULT_EXAMPLE_THREAD_TOGGLE
help
Enables creating and aborting an example thread every 10 seconds in the
example app

config ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS
bool "Use metrics to monitor memory usage in the example app"
default y
depends on MEMFAULT

endmenu

source "Kconfig.zephyr"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MEMFAULT_METRICS_KEY_DEFINE(MainStack_MinBytesFree, kMemfaultMetricType_Unsigned)
7 changes: 7 additions & 0 deletions examples/zephyr/qemu/qemu-app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_SHELL=y

# This makes the qemu guest run closer to real time instead of super fast
CONFIG_QEMU_ICOUNT=n

CONFIG_LOG=y
# LOG v2 option, only for pre zephyr-v3.1.0
# CONFIG_LOG2_MODE_DEFERRED=y
Expand All @@ -18,3 +21,7 @@ CONFIG_LOG_BACKEND_UART=y
# backend. Note that the RTT backend is enabled by default- that's ok, and could
# be useful if the board doesn't have a UART available.
CONFIG_SHELL_LOG_BACKEND=n

CONFIG_SYS_HEAP_RUNTIME_STATS=y
CONFIG_HEAP_MEM_POOL_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
106 changes: 106 additions & 0 deletions examples/zephyr/qemu/qemu-app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,30 @@
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <shell/shell.h>
#include <logging/log.h>
#include <zephyr.h>

#include "memfault/components.h"

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS
//! Size of memory to allocate on main stack
//! This requires a larger allocation due to the method used to measure stack usage
#define STACK_ALLOCATION_SIZE (CONFIG_MAIN_STACK_SIZE >> 2)
//! Size of memory to allocate on system heap
#define HEAP_ALLOCATION_SIZE (CONFIG_HEAP_MEM_POOL_SIZE >> 3)
//! Value to sleep for observing metrics changes
#define METRICS_OBSERVE_PERIOD MEMFAULT_METRICS_HEARTBEAT_INTERVAL_SECS

//! Array of heap pointers
static void *heap_ptrs[4] = {NULL};

//! Keep a reference to the main thread for stack info
static struct k_thread *s_main_thread = NULL;
#endif // CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS

// Blink code taken from the zephyr/samples/basic/blinky example.
static void blink_forever(void) {
#if CONFIG_QEMU_TARGET
Expand Down Expand Up @@ -98,10 +115,99 @@ static void prv_init_test_thread_timer(void) {
static void prv_init_test_thread_timer(void) {}
#endif // CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_THREAD_TOGGLE

#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS

//! Helper function to collect metric value on main thread stack usage.
static void prv_collect_main_thread_stack_free(void) {
if (s_main_thread == NULL) {
return;
}

size_t unused = 0;
int rc = k_thread_stack_space_get(s_main_thread, &unused);
if (rc == 0) {
rc = memfault_metrics_heartbeat_set_unsigned(MEMFAULT_METRICS_KEY(MainStack_MinBytesFree), unused);
if (rc) {
LOG_ERR("Error[%d] setting MainStack_MinBytesFree", rc);
}
} else {
LOG_ERR("Error getting thread stack usage[%d]", rc);
}
}

//! Shell function to exercise example memory metrics
//!
//! This function demonstrates the change in stack and heap memory metrics
//! as memory is allocated and deallocated from these regions.
//!
//! @warning This code uses `memfault_metrics_heartbeat_debug_trigger` which is not intended
//! to be used in production code. This functions use here is solely to demonstrate the metrics
//! values changing. Production applications should rely on the heartbeat timer to trigger
//! collection
static int prv_run_example_memory_metrics(const struct shell *shell, size_t argc, char **argv) {
ARG_UNUSED(shell);
ARG_UNUSED(argc);
ARG_UNUSED(argv);

if (s_main_thread == NULL) {
return 0;
}

// Next two loops demonstrate heap usage metric
for (size_t i = 0; i < ARRAY_SIZE(heap_ptrs); i++) {
heap_ptrs[i] = k_malloc(HEAP_ALLOCATION_SIZE);
}

// Collect data after allocation
memfault_metrics_heartbeat_debug_trigger();

for (size_t i = 0; i < ARRAY_SIZE(heap_ptrs); i++) {
k_free(heap_ptrs[i]);
heap_ptrs[i] = NULL;
}

// Collect data after deallocation
memfault_metrics_heartbeat_debug_trigger();
return 0;
}

SHELL_CMD_REGISTER(memory_metrics, NULL, "Collects runtime memory metrics from application", prv_run_example_memory_metrics);

// Override function to collect the app metric MainStack_MinBytesFree
// and print current metric values
void memfault_metrics_heartbeat_collect_data(void) {
prv_collect_main_thread_stack_free();
memfault_metrics_heartbeat_debug_print();
}

//! Helper function to demonstrate changes in stack metrics
static void prv_run_stack_metrics_example(void) {
volatile uint8_t stack_array[STACK_ALLOCATION_SIZE];
memset((uint8_t *)stack_array, 0, STACK_ALLOCATION_SIZE);
}
#endif // CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS

void main(void) {
LOG_INF("👋 Memfault Demo App! Board %s\n", CONFIG_BOARD);
memfault_device_info_dump();

#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS
s_main_thread = k_current_get();

// @warning This code uses `memfault_metrics_heartbeat_debug_trigger` which is not intended
// to be used in production code. This functions use here is solely to demonstrate the metrics
// values changing. Production applications should rely on the heartbeat timer to trigger
// collection

// Collect a round of metrics to show initial stack usage
memfault_metrics_heartbeat_debug_trigger();

prv_run_stack_metrics_example();

// Collect another round to show change in stack metrics
memfault_metrics_heartbeat_debug_trigger();
#endif

prv_init_test_thread_timer();

blink_forever();
Expand Down
16 changes: 16 additions & 0 deletions ports/stm32cube/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Memfault Port File for STM32CubeSDK

These port files provide one or more of the following platform implementations
for select STM32 chip families:

- **Reboot Reason**
- **Coredump Platform Storage**
- **Watchdog Integration**

The ports are designed to be used with the STM32CubeSDK CMSIS and HAL.

ST maintains a list of publicly-available STM32CubeSDKs here:

[https://github.com/STMicroelectronics/STM32Cube_MCU_Overall_Offer#stm32cube-mcu-packages](https://github.com/STMicroelectronics/STM32Cube_MCU_Overall_Offer/tree/73403531e57d5789650230379d407e0e9bf415fe#stm32cube-mcu-packages)

See the individual port files for details.
1 change: 1 addition & 0 deletions ports/zephyr/common/memfault_platform_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "memfault/core/platform/core.h"

#include <init.h>
#include <kernel.h>
#include <soc.h>

#include "memfault/components.h"
Expand Down
2 changes: 1 addition & 1 deletion ports/zephyr/common/memfault_platform_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include "memfault/core/platform/core.h"

#include <init.h>
#include <kernel.h>

K_MUTEX_DEFINE(s_memfault_mutex);

Expand Down
Loading

0 comments on commit ac6cb05

Please sign in to comment.