Skip to content

Commit

Permalink
Memfault Firmware SDK 0.31.1 (Build 458093)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Jun 17, 2022
1 parent cdb5fdb commit 14362a7
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 21 deletions.
26 changes: 22 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
### Changes between Memfault SDK 0.31.1 and SDK 0.31.0 - June 16, 2022

#### :chart_with_upwards_trend: Improvements

- Enable the Zephyr fault handler (including console fault prints) after
Memfault handler runs. Can be disabled by implementing
`memfault_platform_reboot()`. See details in
[ports/zephyr/include/memfault/ports/zephyr/coredump.h](ports/zephyr/include/memfault/ports/zephyr/coredump.h)

#### :house: Internal

- Fixed compiler error in
[nRF91 sample test app](examples/nrf-connect-sdk/nrf9160/memfault_demo_app)
when compiling with the nRF Connect SDK v2.0.0 release

### Changes between Memfault SDK 0.31.0 and SDK 0.30.5 - June 6, 2022

#### :chart_with_upwards_trend: Improvements

- Added reference port for [CAT1A (PSoC:tm: 6)](https://github.com/Infineon/mtb-pdl-cat1) based
MCUs using the
- Added reference port for
[CAT1A (PSoC:tm: 6)](https://github.com/Infineon/mtb-pdl-cat1) based MCUs
using the
[ModusToolbox:tm: Software](https://www.infineon.com/cms/en/design-support/tools/sdk/modustoolbox-software/)
stack. For more details see [ports/cypress/psoc6](ports/cypress/psoc6) directory.
- - Added a convenience utility function for posting chunks using the Memfault http client. See
stack. For more details see [ports/cypress/psoc6](ports/cypress/psoc6)
directory.
- Added a convenience utility function for posting chunks using the Memfault
http client. See
[`memfault_http_client_post_chunk`](components/include/memfault/http/http_client.h#L101)
for more details!

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: 451641
GIT COMMIT: 963211879
BUILD ID: 458093
GIT COMMIT: b7d0794c4
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 = 31, .patch = 0 }
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 31, .patch = 1 }

#ifdef __cplusplus
}
Expand Down
35 changes: 22 additions & 13 deletions examples/nrf-connect-sdk/nrf9160/memfault_demo_app/src/watchdog.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
//! Example configuration of Zephyr hardware watchdog with Memfault software watchdog
//! port such that a coredump is captured ahead of the hardware watchdog firing

#include <zephyr.h>
#include <device.h>
#include <version.h>
#include "memfault/ports/watchdog.h"

#include <device.h>
#include <drivers/watchdog.h>
#include <version.h>
#include <zephyr.h>

#include "memfault/core/debug_log.h"
#include "memfault/ports/watchdog.h"

//! Note: The timeout must be large enough to give us enough time to capture a coredump
//! before the system resets
#define MEMFAULT_WATCHDOG_HW_TIMEOUT_SECS (MEMFAULT_WATCHDOG_SW_TIMEOUT_SECS + 10)

#define WDT_MAX_WINDOW (MEMFAULT_WATCHDOG_HW_TIMEOUT_SECS * 1000)
#define WDT_MAX_WINDOW (MEMFAULT_WATCHDOG_HW_TIMEOUT_SECS * 1000)

#define WATCHDOG_TASK_STACK_SIZE 512
K_THREAD_STACK_DEFINE(s_wdt_task_stack_area, WATCHDOG_TASK_STACK_SIZE);
Expand All @@ -32,10 +32,21 @@ static const struct device *s_wdt = NULL;
#endif

#if KERNEL_VERSION_MAJOR == 2 && KERNEL_VERSION_MINOR < 3
#define WDT_DEV_NAME DT_WDT_0_NAME
#define WDT_DEV_NAME DT_WDT_0_NAME
#else
#define WDT_NODE DT_INST(0, nordic_nrf_watchdog)
#define WDT_DEV_NAME DT_LABEL(WDT_NODE)
//! Watchdog device tree name changed in NCS v2.0.0 :
//! https://github.com/nrfconnect/sdk-zephyr/blob/12ee4d5f4b99acef542ce3977cb9078fcbb36d82/dts/arm/nordic/nrf9160_common.dtsi#L368
//! Pick the one that's available in the current SDK version.
#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt)
#define WDT_NODE_NAME nordic_nrf_wdt
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_watchdog)
#define WDT_NODE_NAME nordic_nrf_watchdog
#else
#error "No compatible watchdog instance for this configuration!"
#endif

#define WDT_NODE DT_INST(0, WDT_NODE_NAME)
#define WDT_DEV_NAME DT_LABEL(WDT_NODE)
#endif

static int s_wdt_channel_id = -1;
Expand All @@ -51,8 +62,8 @@ void memfault_demo_app_watchdog_feed(void) {

//! A basic watchdog implementation
//!
//! Once Zephyr has a Software & Task watchdog in place, the example will be updated to make use of that
//! For more info about watchdog setup in general, see https://mflt.io/root-cause-watchdogs
//! Once Zephyr has a Software & Task watchdog in place, the example will be updated to make use of
//! that For more info about watchdog setup in general, see https://mflt.io/root-cause-watchdogs
static void prv_wdt_task(void *arg1, void *arg2, void *arg3) {
while (1) {
k_sleep(K_SECONDS(1));
Expand Down Expand Up @@ -97,8 +108,6 @@ void memfault_demo_app_watchdog_boot(void) {
// cause the watchdog to not be fed
memfault_software_watchdog_enable();
k_thread_create(&my_thread_data, s_wdt_task_stack_area,
K_THREAD_STACK_SIZEOF(s_wdt_task_stack_area),
prv_wdt_task,
NULL, NULL, NULL,
K_THREAD_STACK_SIZEOF(s_wdt_task_stack_area), prv_wdt_task, NULL, NULL, NULL,
K_LOWEST_APPLICATION_THREAD_PRIO, 0, K_NO_WAIT);
}
7 changes: 6 additions & 1 deletion ports/templates/memfault_platform_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,18 @@ int memfault_platform_boot(void) {
memfault_device_info_dump();
memfault_platform_reboot_tracking_boot();

// initialize the event storage buffer
static uint8_t s_event_storage[1024];
const sMemfaultEventStorageImpl *evt_storage =
memfault_events_storage_boot(s_event_storage, sizeof(s_event_storage));
memfault_events_storage_boot(s_event_storage, sizeof(s_event_storage));

// configure trace events to store into the buffer
memfault_trace_event_boot(evt_storage);

// record the current reboot reason
memfault_reboot_tracking_collect_reset_info(evt_storage);

// configure the metrics component to store into the buffer
sMemfaultMetricBootInfo boot_info = {
.unexpected_reboot_count = memfault_reboot_tracking_get_crash_count(),
};
Expand Down
10 changes: 10 additions & 0 deletions ports/zephyr/include/memfault/ports/zephyr/coredump.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ size_t memfault_zephyr_get_bss_regions(sMfltCoredumpRegion *regions, size_t num_
//! be <= num_regions
size_t memfault_zephyr_get_data_regions(sMfltCoredumpRegion *regions, size_t num_regions);

//! Run the Zephyr z_fatal_error function. This is used to execute the Zephyr
//! error console prints, which are suppressed due to the Memfault fault handler
//! replacing the z_fatal_error function at link time.
//!
//! This can be useful when locally debugging without a debug probe connected.
//! It's called as part of the built-in implementation of
//! memfault_platform_reboot(); if a user-implemented version of that function
//! is used, this function can be called from there.
void memfault_zephyr_z_fatal_error(void);

#ifdef __cplusplus
}
#endif
34 changes: 34 additions & 0 deletions ports/zephyr/v2.4/memfault_fault_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ extern void sys_arch_reboot(int type);

// Intercept zephyr/kernel/fatal.c:z_fatal_error()
void __wrap_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf);
extern void __real_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf);

// This struct stores the crash info for later passing to __real_z_fatal_error
static struct save_crash_info {
bool valid;
unsigned int reason;
z_arch_esf_t esf;
} s_save_crash_info;

// stash the reason and esf for later use by zephyr unwinder
static void prv_save_crash_info(unsigned int reason, const z_arch_esf_t *esf) {
s_save_crash_info.valid = true;
s_save_crash_info.reason = reason;
s_save_crash_info.esf = *esf;
}

void __wrap_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) {
const struct __extra_esf_info *extra_info = &esf->extra_info;
Expand All @@ -64,13 +79,32 @@ void __wrap_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) {
.r11 = callee_regs->v8,
.exc_return = exc_return ,
};

prv_save_crash_info(reason, esf);

memfault_fault_handler(&reg, kMfltRebootReason_HardFault);
}

void memfault_zephyr_z_fatal_error(void) {
if (s_save_crash_info.valid) {
unsigned int reason = K_ERR_KERNEL_OOPS;
z_arch_esf_t *esf = NULL;
if (s_save_crash_info.valid) {
reason = s_save_crash_info.reason;
esf = &s_save_crash_info.esf;
}

__real_z_fatal_error(reason, esf);
}
}

MEMFAULT_WEAK
MEMFAULT_NORETURN
void memfault_platform_reboot(void) {
memfault_platform_halt_if_debugging();

memfault_zephyr_z_fatal_error();

sys_arch_reboot(0);
CODE_UNREACHABLE;
}
5 changes: 5 additions & 0 deletions scripts/mflt-build-id/tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
# See License.txt for details
#

# flake8: noqa: M900

# We don't have invoke in the requirements because this is used by *other* packages,
# not by this package itself.

import invoke


Expand Down

0 comments on commit 14362a7

Please sign in to comment.