Skip to content

Commit

Permalink
Memfault Firmware SDK 0.33.0 (Build 497178)
Browse files Browse the repository at this point in the history
  • Loading branch information
Memfault Inc committed Aug 18, 2022
1 parent 36a6345 commit 969baaf
Show file tree
Hide file tree
Showing 31 changed files with 671 additions and 60 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 0.33.0 and SDK 0.32.2 - Aug 18, 2022

#### :chart_with_upwards_trend: Improvements

- Extend [memfault demo shell](components/demo/src/memfault_demo_shell.c) to
support terminals that only emit CR for line endings
- nRF5 SDK Updates:
- Added a [software watchdog](https://mflt.io/root-cause-watchdogs) reference
port for nRF5 SDK which makes use of the RTC Peripheral. See
[ports/nrf5_sdk/software_watchdog.c](ports/nrf5_sdk/software_watchdog.c) for
more details.
- Updated [nRF5 example app](examples/nrf5/apps/memfault_demo_app/) to make
use of hardware and new software watchdog port.
- Zephyr Port Updates:
- Added Kconfig option to fallback to using `printk` by default when no
logging is enabled. This can be disabled by setting
`CONFIG_MEMFAULT_PLATFORM_LOG_FALLBACK_TO_PRINTK=n`.
- nRF Connect SDK Updates:
- Fixed a :bug: which could result in download errors when using
[Memfault nRF Connect SDK FOTA client](ports/nrf-connect-sdk/zephyr/include/memfault/nrfconnect_port/fota.h)
and enabled client in example application by default.
- Added new example application for trying Memfault with nRF53 & nRF52 based
development kits. See
[examples/nrf-connect-sdk/nrf5](examples/nrf-connect-sdk/nrf5) for more
details.

### Changes between Memfault SDK 0.32.2 and SDK 0.32.1 - Aug 16, 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: 494632
GIT COMMIT: b2b683510
BUILD ID: 497178
GIT COMMIT: 3f51dc76a
32 changes: 30 additions & 2 deletions components/demo/src/memfault_demo_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
static struct MemfaultShellContext {
int (*send_char)(char c);
size_t rx_size;
// the char we will ignore when received end-of-line sequences
char eol_ignore_char;
char rx_buffer[MEMFAULT_DEMO_SHELL_RX_BUFFER_SIZE];
} s_mflt_shell;

Expand All @@ -43,7 +45,7 @@ static void prv_send_char(char c) {
}

static void prv_echo(char c) {
if ('\n' == c) {
if (c == '\n') {
prv_send_char('\r');
prv_send_char('\n');
} else if ('\b' == c) {
Expand Down Expand Up @@ -129,13 +131,34 @@ static void prv_process(void) {
}

void memfault_demo_shell_boot(const sMemfaultShellImpl *impl) {
s_mflt_shell.eol_ignore_char = 0;
s_mflt_shell.send_char = impl->send_char;
prv_reset_rx_buffer();
prv_echo_str("\n" MEMFAULT_SHELL_PROMPT);
}

//! Logic to deal with CR, LF, CRLF, or LFCR end-of-line (EOL) sequences
//! @return true if the character should be ignored, false otherwise
static bool prv_should_ignore_eol_char(char c) {
if (s_mflt_shell.eol_ignore_char != 0) {
return (c == s_mflt_shell.eol_ignore_char);
}

//
// First end of line character detected. We will use this character as our EOL delimiter and
// ignore the opposite character when we see it in the future.
//

if (c == '\r') {
s_mflt_shell.eol_ignore_char = '\n';
} else if (c == '\n') {
s_mflt_shell.eol_ignore_char = '\r';
}
return false;
}

void memfault_demo_shell_receive_char(char c) {
if (c == '\r' || prv_is_rx_buffer_full() || !prv_booted()) {
if (prv_should_ignore_eol_char(c) || prv_is_rx_buffer_full() || !prv_booted()) {
return;
}

Expand All @@ -144,6 +167,11 @@ void memfault_demo_shell_receive_char(char c) {
return; // nothing left to delete so don't echo the backspace
}

// CR are our EOL delimiter. Remap as a LF here since that's what internal handling logic expects
if (c == '\r') {
c = '\n';
}

prv_echo(c);

if (is_backspace) {
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 = 32, .patch = 2 }
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 33, .patch = 0 }

#ifdef __cplusplus
}
Expand Down
11 changes: 11 additions & 0 deletions examples/nrf-connect-sdk/nrf5/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/bootloader
/build
/mbedtls
/modules
/nrf
/nrfxlib
/sparc
/test
/tools
/.west
/zephyr
69 changes: 69 additions & 0 deletions examples/nrf-connect-sdk/nrf5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# nRF-Connect Memfault Example

This is a small example application showing a Memfault integration running on an
nrf52840 development board, using the nRF Connect SDK. Any nRF board should also
work. The example has been tested on:

- nRF52840-DK
- nRF5340-DK

## Usage

Make sure you have the Zephyr / nRF-Connect tools installed first:

<https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.0.2/nrf/gs_installing.html>

To build and flash this example to an nRF52840-DK (PCA10056), run the following
commands:

```bash
❯ west init --local memfault_demo_app
❯ west update
❯ west build --board nrf52840dk_nrf52840 memfault_demo_app
❯ west flash
```

Open a serial terminal to access the console:

```bash
# for example, pypserial-miniterm
❯ pyserial-miniterm --raw /dev/ttyACM0 115200
```

The console has several Memfault test commands available:

```bash
uart:~$ mflt help
mflt - Memfault Test Commands
Subcommands:
reboot :trigger a reboot and record it using memfault
get_core :gets the core
clear_core :clear the core
crash :trigger a crash
test_log :Writes test logs to log buffer
trigger_logs :Trigger capture of current log buffer contents
hang :trigger a hang to test watchdog functionality
export :dump chunks collected by Memfault SDK using
https://mflt.io/chunk-data-export
trace :Capture an example trace event
get_device_info :display device information
post_chunks :Post Memfault data to cloud
trigger_heartbeat :Trigger an immediate capture of all heartbeat metrics
get_latest_release :checks to see if new ota payload is available
```
For example, to test the coredump functionality:
1. run `mflt crash` and wait for the board to reset
2. run `mflt get_core` to confirm the coredump was saved
3. run `mflt export` to print out the base-64 chunks:
```plaintext
uart:~$ mflt export
<inf> <mflt>: MC:SE4DpwIEAwEKbW5yZjUyX2V4YW1wbGUJZTAuMC4xBmFhC0Z5RE1gF8EEhgFpSW5mbyBsb2chAmxXYXJuaW5nIGxvZyEDakVycm9yIGxvZyE=:
<inf> <mflt>: MC:gE6A/A==:
```
4. upload the chunks to Memfault. see here for details:
<https://mflt.io/chunks-debug>
28 changes: 28 additions & 0 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(fs_shell)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

zephyr_include_directories(config)

# Normalize dbug + __FILE__ paths to relative locations:
# 1. west workspace
# 2. toolchain install location (applies to paths in cross tool library files)
#
# If debugging from location 1., the west-manifest files should already have the
# correct relative path for GDB to locate them, otherwise the GDB "directory"
# command can be used to tell GDB where to find the source files (also required
# if the cross tool libraries/headers need to be located by GDB)
get_filename_component(WEST_PROJECT_ROOT_PATH
"${CMAKE_CURRENT_LIST_DIR}/.."
ABSOLUTE)
zephyr_compile_options(
-ffile-prefix-map=${WEST_PROJECT_ROOT_PATH}=.
-ffile-prefix-map=${TOOLCHAIN_HOME}=.
-Wa,--debug-prefix-map=${WEST_PROJECT_ROOT_PATH}=.
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

//! @file
//!
//! Copyright (c) Memfault, Inc.
//! See License.txt for details
//!
//! Platform overrides for the default configuration settings in the memfault-firmware-sdk.
//! Default configuration settings can be found in "memfault/config.h"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This is where project specific trace reasons should be defined
// using the MEMFAULT_TRACE_REASON_DEFINE macro
//
// For example:
// MEMFAULT_TRACE_REASON_DEFINE(your_custom_error_reason)
49 changes: 49 additions & 0 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=4096

CONFIG_SHELL=y
CONFIG_SHELL_LOG_LEVEL_INF=y

# hwinfo is used to get a unique device id from the chip id
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
CONFIG_PM_PARTITION_SIZE_MEMFAULT_STORAGE=0x20000

# set a dummy project key; this setting is required by the nrf-connect
# integration, but it is unused in a non-HTTP application
CONFIG_MEMFAULT_NCS_PROJECT_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Set device information fields
CONFIG_MEMFAULT_NCS_DEVICE_ID_RUNTIME=y
CONFIG_MEMFAULT_NCS_HW_VERSION="a"
CONFIG_MEMFAULT_NCS_FW_TYPE="nrf52_example"
CONFIG_MEMFAULT_NCS_FW_VERSION_STATIC=y
CONFIG_MEMFAULT_NCS_FW_VERSION="0.0.1"

# Enable and configure logging
CONFIG_LOG=y
CONFIG_LOG_BACKEND_UART=y
# Disable the shell log backend. Rely on the configured backend instead (RTT,
# UART, etc.)
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 capture of recent logs as part of a coredump
CONFIG_MEMFAULT_LOGGING_ENABLE=y

# Enable Flash and Bootloader components for for flash-backed coredump storage
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUBOOT_IMG_MANAGER=y
CONFIG_IMG_MANAGER=y
CONFIG_FLASH=y

CONFIG_WATCHDOG=y
4 changes: 4 additions & 0 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sample:
description: Memfault SDK example integration built on top of the Zephyr FS
shell sample app, with the nRF Connect SDK
name: Memfault Demo App
46 changes: 46 additions & 0 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! @file
//!
//! Copyright (c) Memfault, Inc.
//! See License.txt for details
//!
//! Example console main

#include <drivers/hwinfo.h>
#include <logging/log.h>
#include <memfault/components.h>
#include <memfault_ncs.h>
#include <stdio.h>

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

static void prv_set_device_id(void) {
uint8_t dev_id[16] = {0};
char dev_id_str[sizeof(dev_id) * 2 + 1];
char *dev_str = "UNKNOWN";

// Obtain the device id
ssize_t length = hwinfo_get_device_id(dev_id, sizeof(dev_id));

// If this fails for some reason, use a fixed ID instead
if (length <= 0) {
dev_str = CONFIG_SOC_SERIES "-test";
length = strlen(dev_str);
} else {
// Render the obtained serial number in hexadecimal representation
for (size_t i = 0; i < length; i++) {
(void)snprintf(&dev_id_str[i * 2], sizeof(dev_id_str), "%02x", dev_id[i]);
}
dev_str = dev_id_str;
}

LOG_INF("Device ID: %s", dev_str);

memfault_ncs_device_id_set(dev_str, length * 2);
}

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

memfault_device_info_dump();
}
18 changes: 18 additions & 0 deletions examples/nrf-connect-sdk/nrf5/memfault_demo_app/west.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
manifest:
remotes:
- name: nrf-connect-sdk
url-base: https://github.com/nrfconnect
projects:
- name: nrf
url: https://github.com/nrfconnect/sdk-nrf
revision: v2.0.2
import: true

# Adding the memfault-firmware-sdk module here overrides the version the nRF
# Connect SDK would normally import above
- name: memfault-firmware-sdk
url: https://github.com/memfault/memfault-firmware-sdk
path: modules/lib/memfault-firmware-sdk
revision: master
self:
path: memfault_demo_app
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ if (NCS_VERSION_MAJOR)
# Legacy name for CONFIG_DEBUG_THREAD_INFO needed for nRF Connect version <= 1.5
# due to the version of Zephyr included (pre v2.5)
set(CONFIG_OPENOCD_SUPPORT n CACHE INTERNAL "")

elseif (${NCS_VERSION_MAJOR} LESS_EQUAL 1 AND ${NCS_VERSION_MINOR} LESS 6 )
# Required for logging to work from crash, deprecated in Zephyr included in NCS 1.6
set(CONFIG_LOG_IMMEDIATE y CACHE INTERNAL "")
Expand All @@ -43,6 +42,20 @@ if (NCS_VERSION_MAJOR)
set(CONFIG_NEWLIB_LIBC y CACHE INTERNAL "")
endif()

# Enable Memfault FOTA Support
#
# We enable conditionally because prior to NCS < 1.4 a small patch (https://mflt.io/nrf-fota) was
# needed in order for things to work
if (${NCS_VERSION_MAJOR}.${NCS_VERSION_MINOR}.${NCS_VERSION_PATCH} GREATER_EQUAL 1.5.0)
set(CONFIG_MEMFAULT_FOTA y CACHE INTERNAL "")
set(CONFIG_DOWNLOAD_CLIENT_MAX_FILENAME_SIZE 400 CACHE INTERNAL "")
set(CONFIG_DOWNLOAD_CLIENT_STACK_SIZE 1600 CACHE INTERNAL "")

# Note: Can optionally be changed to =y to implement
# a custom event handler for FOTA events
# CONFIG_MEMFAULT_FOTA_DOWNLOAD_CALLBACK_CUSTOM=n
endif()

# These were removed in NCS 1.8.0, but are needed prior to that. Enable them
# if NCS version <1.7.99 (.99 patch version is used for the next revision's
# development series)
Expand Down
Loading

0 comments on commit 969baaf

Please sign in to comment.