Skip to content

Commit

Permalink
Memfault Firmware SDK 1.8.0 (Build 7456)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Apr 17, 2024
1 parent 0174f3e commit 4cbf8f4
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 19 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ 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.8.0] - 2024-04-17

### :chart_with_upwards_trend: Improvements

- General:
- Scale values now fully supported. This metric metadata will scale down
metric values by the specified factor. Metrics with no specified scale value
will not be scaled
- Fix a :bug: that would reset metric values after running a session start
callback. This prevented setting metrics at the start of a session.
- Zephyr:
- Add a metric using a scale value to our Zephyr QEMU example. This metric
measures CPU usage (in permille, 0.0-100.0%) of the main thread.

## [1.7.7] - 2024-04-15

- FreeRTOS:
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: 7396
GIT COMMIT: 4b94654821
VERSION: 1.7.7
BUILD ID: 7456
GIT COMMIT: 69ebc0be9a
VERSION: 1.8.0
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 = 7, .patch = 7 }
#define MEMFAULT_SDK_VERSION_STR "1.7.7"
#define MEMFAULT_SDK_VERSION { .major = 1, .minor = 8, .patch = 0 }
#define MEMFAULT_SDK_VERSION_STR "1.8.0"

#ifdef __cplusplus
}
Expand Down
10 changes: 5 additions & 5 deletions components/metrics/src/memfault_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1017,11 +1017,6 @@ int memfault_metrics_heartbeat_read_string(MemfaultMetricId key, char *read_val,
}

int memfault_metrics_session_start(eMfltMetricsSessionIndex session_key) {
MemfaultMetricsSessionStartCb session_start_cb = s_session_start_cbs[session_key];
if (session_start_cb != NULL) {
session_start_cb();
}

int rv;
memfault_lock();
{
Expand All @@ -1034,6 +1029,11 @@ int memfault_metrics_session_start(eMfltMetricsSessionIndex session_key) {
}
memfault_unlock();

MemfaultMetricsSessionStartCb session_start_cb = s_session_start_cbs[session_key];
if (session_start_cb != NULL) {
session_start_cb();
}

return rv;
}

Expand Down
8 changes: 5 additions & 3 deletions examples/zephyr/qemu/qemu-app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ config ZEPHYR_MEMFAULT_EXAMPLE_THREAD_TOGGLE
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"
config ZEPHYR_MEMFAULT_EXAMPLE_METRICS
bool "Use metrics to monitor memory usage and execution time in the example app"
default y
depends on MEMFAULT && MEMFAULT_HEAP_STATS && THREAD_STACK_INFO
depends on MEMFAULT && MEMFAULT_HEAP_STATS
depends on THREAD_STACK_INFO
depends on THREAD_RUNTIME_STATS

config ZEPHYR_MEMFAULT_EXAMPLE_SOFTWARE_VERSION
string "Software Version"
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
MEMFAULT_METRICS_KEY_DEFINE(MainStack_MinBytesFree, kMemfaultMetricType_Unsigned)
// This example metric demonstrates a permille integer with a range of 0-1000 to be translated into
// a percentage 0.0-100.0%
MEMFAULT_METRICS_KEY_DEFINE_WITH_SCALE_VALUE(main_thread_cpu_time_permille, kMemfaultMetricType_Unsigned, 10)
3 changes: 3 additions & 0 deletions examples/zephyr/qemu/qemu-app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,6 @@ CONFIG_MEMFAULT_SHELL_SELF_TEST_COREDUMP_STORAGE=y

# Enable warnings as errors
CONFIG_COMPILER_WARNINGS_AS_ERRORS=y

# Enable Thread run-time stats
CONFIG_THREAD_RUNTIME_STATS=y
40 changes: 35 additions & 5 deletions examples/zephyr/qemu/qemu-app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS
#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_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)
Expand All @@ -36,7 +36,7 @@ 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
#endif // CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_METRICS

// Blink code taken from the zephyr/samples/basic/blinky example.
static void blink_forever(void) {
Expand Down Expand Up @@ -122,7 +122,7 @@ 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
#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_METRICS

//! Helper function to collect metric value on main thread stack usage.
static void prv_collect_main_thread_stack_free(void) {
Expand All @@ -142,6 +142,35 @@ static void prv_collect_main_thread_stack_free(void) {
}
}

static void prv_collect_main_thread_run_stats(void) {
static uint64_t s_prev_main_thread_cycles = 0;
static uint64_t s_prev_cpu_all_cycles = 0;

if (s_main_thread == NULL) {
return;
}

k_thread_runtime_stats_t rt_stats_main = { 0 };
k_thread_runtime_stats_t rt_stats_all = { 0 };

k_thread_runtime_stats_get(s_main_thread, &rt_stats_main);
k_thread_runtime_stats_all_get(&rt_stats_all);

// Calculate difference since last heartbeat
uint64_t current_main_thread_cycles = rt_stats_main.execution_cycles - s_prev_main_thread_cycles;
// Note: execution_cycles = idle + non-idle, total_cycles = non-idle
uint64_t current_cpu_total_cycles = rt_stats_all.execution_cycles - s_prev_cpu_all_cycles;

// Calculate permille of main thread execution vs total CPU time
// Multiply permille factor first to avoid truncating lower bits after integer division
uint32_t main_thread_cpu_time = (current_main_thread_cycles * 1000) / current_cpu_total_cycles;
MEMFAULT_METRIC_SET_UNSIGNED(main_thread_cpu_time_permille, main_thread_cpu_time);

// Update previous values
s_prev_main_thread_cycles = current_main_thread_cycles;
s_prev_cpu_all_cycles = current_cpu_total_cycles;
}

//! Shell function to exercise example memory metrics
//!
//! This function demonstrates the change in stack and heap memory metrics
Expand Down Expand Up @@ -185,6 +214,7 @@ SHELL_CMD_REGISTER(memory_metrics, NULL, "Collects runtime memory metrics from a
// and print current metric values
void memfault_metrics_heartbeat_collect_data(void) {
prv_collect_main_thread_stack_free();
prv_collect_main_thread_run_stats();
memfault_metrics_heartbeat_debug_print();
}

Expand All @@ -193,7 +223,7 @@ 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
#endif // CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_METRICS

#if defined(CONFIG_MEMFAULT_FAULT_HANDLER_RETURN)
#include MEMFAULT_ZEPHYR_INCLUDE(fatal.h)
Expand All @@ -213,7 +243,7 @@ int main(void) {
memfault_zephyr_collect_reset_info();
#endif

#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_MEMORY_METRICS
#if CONFIG_ZEPHYR_MEMFAULT_EXAMPLE_METRICS
s_main_thread = k_current_get();

// @warning This code uses `memfault_metrics_heartbeat_debug_trigger` which is not intended
Expand Down
2 changes: 1 addition & 1 deletion scripts/memfault_gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ def _create_http_connection(base_uri):
else:
conn_class = HTTPSConnection
default_port = 443
port = url.port if url.port else default_port
port = url.port or default_port
return conn_class(url.hostname, port=port)


Expand Down
26 changes: 26 additions & 0 deletions tests/src/test_memfault_session_metrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ static void session_end_cb(void) {
}

static void session_start_cb(void) {
// Set a metric value to ensure that metrics are reset before session_start_cb
memfault_metrics_heartbeat_set_unsigned(MEMFAULT_METRICS_KEY(test_session_key_unsigned), 1);
mock().actualCall(__func__);
}

Expand Down Expand Up @@ -141,10 +143,34 @@ TEST(MemfaultSessionMetrics, Test_RegisterSessionStartCb) {
mock().expectOneCall("memfault_metrics_session_serialize");
mock().expectOneCall("session_start_cb");

// Check that a session metric is unset before the session starts
uint32_t val = 0;
int rv =
memfault_metrics_heartbeat_read_unsigned(MEMFAULT_METRICS_KEY(test_session_key_unsigned), &val);

LONGS_EQUAL(-7, rv);
LONGS_EQUAL(0, val);

memfault_metrics_session_register_start_cb(MEMFAULT_METRICS_SESSION_KEY(test_key_session),
session_start_cb);
MEMFAULT_METRICS_SESSION_START(test_key_session);

// Check that the metric is set after the session starts. Metric is set within the start callback
rv =
memfault_metrics_heartbeat_read_unsigned(MEMFAULT_METRICS_KEY(test_session_key_unsigned), &val);

LONGS_EQUAL(0, rv);
LONGS_EQUAL(1, val);

MEMFAULT_METRICS_SESSION_END(test_key_session);

// Check that the metric is set after the session ends. Metrics are reset at session start, not
// end
rv =
memfault_metrics_heartbeat_read_unsigned(MEMFAULT_METRICS_KEY(test_session_key_unsigned), &val);

LONGS_EQUAL(0, rv);
LONGS_EQUAL(1, val);
}

TEST(MemfaultSessionMetrics, Test_RegisterSessionEndCb) {
Expand Down

0 comments on commit 4cbf8f4

Please sign in to comment.