Skip to content

Commit 14362a7

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 0.31.1 (Build 458093)
1 parent cdb5fdb commit 14362a7

File tree

8 files changed

+102
-21
lines changed

8 files changed

+102
-21
lines changed

CHANGES.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
1+
### Changes between Memfault SDK 0.31.1 and SDK 0.31.0 - June 16, 2022
2+
3+
#### :chart_with_upwards_trend: Improvements
4+
5+
- Enable the Zephyr fault handler (including console fault prints) after
6+
Memfault handler runs. Can be disabled by implementing
7+
`memfault_platform_reboot()`. See details in
8+
[ports/zephyr/include/memfault/ports/zephyr/coredump.h](ports/zephyr/include/memfault/ports/zephyr/coredump.h)
9+
10+
#### :house: Internal
11+
12+
- Fixed compiler error in
13+
[nRF91 sample test app](examples/nrf-connect-sdk/nrf9160/memfault_demo_app)
14+
when compiling with the nRF Connect SDK v2.0.0 release
15+
116
### Changes between Memfault SDK 0.31.0 and SDK 0.30.5 - June 6, 2022
217

318
#### :chart_with_upwards_trend: Improvements
419

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

VERSION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BUILD ID: 451641
2-
GIT COMMIT: 963211879
1+
BUILD ID: 458093
2+
GIT COMMIT: b7d0794c4

components/include/memfault/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ typedef struct {
1919
uint8_t patch;
2020
} sMfltSdkVersion;
2121

22-
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 31, .patch = 0 }
22+
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 31, .patch = 1 }
2323

2424
#ifdef __cplusplus
2525
}

examples/nrf-connect-sdk/nrf9160/memfault_demo_app/src/watchdog.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
//! Example configuration of Zephyr hardware watchdog with Memfault software watchdog
77
//! port such that a coredump is captured ahead of the hardware watchdog firing
88

9-
#include <zephyr.h>
10-
#include <device.h>
11-
#include <version.h>
9+
#include "memfault/ports/watchdog.h"
1210

11+
#include <device.h>
1312
#include <drivers/watchdog.h>
13+
#include <version.h>
14+
#include <zephyr.h>
1415

1516
#include "memfault/core/debug_log.h"
16-
#include "memfault/ports/watchdog.h"
1717

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

22-
#define WDT_MAX_WINDOW (MEMFAULT_WATCHDOG_HW_TIMEOUT_SECS * 1000)
22+
#define WDT_MAX_WINDOW (MEMFAULT_WATCHDOG_HW_TIMEOUT_SECS * 1000)
2323

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

3434
#if KERNEL_VERSION_MAJOR == 2 && KERNEL_VERSION_MINOR < 3
35-
#define WDT_DEV_NAME DT_WDT_0_NAME
35+
#define WDT_DEV_NAME DT_WDT_0_NAME
3636
#else
37-
#define WDT_NODE DT_INST(0, nordic_nrf_watchdog)
38-
#define WDT_DEV_NAME DT_LABEL(WDT_NODE)
37+
//! Watchdog device tree name changed in NCS v2.0.0 :
38+
//! https://github.com/nrfconnect/sdk-zephyr/blob/12ee4d5f4b99acef542ce3977cb9078fcbb36d82/dts/arm/nordic/nrf9160_common.dtsi#L368
39+
//! Pick the one that's available in the current SDK version.
40+
#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt)
41+
#define WDT_NODE_NAME nordic_nrf_wdt
42+
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_watchdog)
43+
#define WDT_NODE_NAME nordic_nrf_watchdog
44+
#else
45+
#error "No compatible watchdog instance for this configuration!"
46+
#endif
47+
48+
#define WDT_NODE DT_INST(0, WDT_NODE_NAME)
49+
#define WDT_DEV_NAME DT_LABEL(WDT_NODE)
3950
#endif
4051

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

5263
//! A basic watchdog implementation
5364
//!
54-
//! Once Zephyr has a Software & Task watchdog in place, the example will be updated to make use of that
55-
//! For more info about watchdog setup in general, see https://mflt.io/root-cause-watchdogs
65+
//! Once Zephyr has a Software & Task watchdog in place, the example will be updated to make use of
66+
//! that For more info about watchdog setup in general, see https://mflt.io/root-cause-watchdogs
5667
static void prv_wdt_task(void *arg1, void *arg2, void *arg3) {
5768
while (1) {
5869
k_sleep(K_SECONDS(1));
@@ -97,8 +108,6 @@ void memfault_demo_app_watchdog_boot(void) {
97108
// cause the watchdog to not be fed
98109
memfault_software_watchdog_enable();
99110
k_thread_create(&my_thread_data, s_wdt_task_stack_area,
100-
K_THREAD_STACK_SIZEOF(s_wdt_task_stack_area),
101-
prv_wdt_task,
102-
NULL, NULL, NULL,
111+
K_THREAD_STACK_SIZEOF(s_wdt_task_stack_area), prv_wdt_task, NULL, NULL, NULL,
103112
K_LOWEST_APPLICATION_THREAD_PRIO, 0, K_NO_WAIT);
104113
}

ports/templates/memfault_platform_port.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,18 @@ int memfault_platform_boot(void) {
105105
memfault_device_info_dump();
106106
memfault_platform_reboot_tracking_boot();
107107

108+
// initialize the event storage buffer
108109
static uint8_t s_event_storage[1024];
109110
const sMemfaultEventStorageImpl *evt_storage =
110-
memfault_events_storage_boot(s_event_storage, sizeof(s_event_storage));
111+
memfault_events_storage_boot(s_event_storage, sizeof(s_event_storage));
112+
113+
// configure trace events to store into the buffer
111114
memfault_trace_event_boot(evt_storage);
112115

116+
// record the current reboot reason
113117
memfault_reboot_tracking_collect_reset_info(evt_storage);
114118

119+
// configure the metrics component to store into the buffer
115120
sMemfaultMetricBootInfo boot_info = {
116121
.unexpected_reboot_count = memfault_reboot_tracking_get_crash_count(),
117122
};

ports/zephyr/include/memfault/ports/zephyr/coredump.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ size_t memfault_zephyr_get_bss_regions(sMfltCoredumpRegion *regions, size_t num_
3939
//! be <= num_regions
4040
size_t memfault_zephyr_get_data_regions(sMfltCoredumpRegion *regions, size_t num_regions);
4141

42+
//! Run the Zephyr z_fatal_error function. This is used to execute the Zephyr
43+
//! error console prints, which are suppressed due to the Memfault fault handler
44+
//! replacing the z_fatal_error function at link time.
45+
//!
46+
//! This can be useful when locally debugging without a debug probe connected.
47+
//! It's called as part of the built-in implementation of
48+
//! memfault_platform_reboot(); if a user-implemented version of that function
49+
//! is used, this function can be called from there.
50+
void memfault_zephyr_z_fatal_error(void);
51+
4252
#ifdef __cplusplus
4353
}
4454
#endif

ports/zephyr/v2.4/memfault_fault_handler.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@ extern void sys_arch_reboot(int type);
4141

4242
// Intercept zephyr/kernel/fatal.c:z_fatal_error()
4343
void __wrap_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf);
44+
extern void __real_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf);
45+
46+
// This struct stores the crash info for later passing to __real_z_fatal_error
47+
static struct save_crash_info {
48+
bool valid;
49+
unsigned int reason;
50+
z_arch_esf_t esf;
51+
} s_save_crash_info;
52+
53+
// stash the reason and esf for later use by zephyr unwinder
54+
static void prv_save_crash_info(unsigned int reason, const z_arch_esf_t *esf) {
55+
s_save_crash_info.valid = true;
56+
s_save_crash_info.reason = reason;
57+
s_save_crash_info.esf = *esf;
58+
}
4459

4560
void __wrap_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) {
4661
const struct __extra_esf_info *extra_info = &esf->extra_info;
@@ -64,13 +79,32 @@ void __wrap_z_fatal_error(unsigned int reason, const z_arch_esf_t *esf) {
6479
.r11 = callee_regs->v8,
6580
.exc_return = exc_return ,
6681
};
82+
83+
prv_save_crash_info(reason, esf);
84+
6785
memfault_fault_handler(&reg, kMfltRebootReason_HardFault);
6886
}
6987

88+
void memfault_zephyr_z_fatal_error(void) {
89+
if (s_save_crash_info.valid) {
90+
unsigned int reason = K_ERR_KERNEL_OOPS;
91+
z_arch_esf_t *esf = NULL;
92+
if (s_save_crash_info.valid) {
93+
reason = s_save_crash_info.reason;
94+
esf = &s_save_crash_info.esf;
95+
}
96+
97+
__real_z_fatal_error(reason, esf);
98+
}
99+
}
100+
70101
MEMFAULT_WEAK
71102
MEMFAULT_NORETURN
72103
void memfault_platform_reboot(void) {
73104
memfault_platform_halt_if_debugging();
105+
106+
memfault_zephyr_z_fatal_error();
107+
74108
sys_arch_reboot(0);
75109
CODE_UNREACHABLE;
76110
}

scripts/mflt-build-id/tasks/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
# See License.txt for details
44
#
55

6+
# flake8: noqa: M900
7+
8+
# We don't have invoke in the requirements because this is used by *other* packages,
9+
# not by this package itself.
10+
611
import invoke
712

813

0 commit comments

Comments
 (0)