Embedded Integration Guide
The following guide will walk you through step-by-step how to integrate and test the Memfault SDK for a Cortex-M device using the GNU GCC, Clang, IAR, ARM MDK, or TI ARM Compiler.
Adding the Memfault Firmware SDK to your device will provide rich diagnostics, including:
Coredump Collection

Device Metrics

Reboot Reason Tracking

Error Tracking with Trace Events

(Optionally) Collect a coredump capture using GDB
- Without GDB
- Using GDB
If you do not use GDB, skip ahead to the next step.
If you use GDB, a full coredump can be captured by just using the debugger! This can be useful during development to take advantage of Memfault's analyzers when a device crashes or hangs.

To perform the capture, navigate to http://app.memfault.com/ and select the "Issues" page in the Memfault UI, click on the "Manual Upload" button, and click on "walk-through on how to upload your first coredump". From there you can follow the guided steps to perform a capture. At the end you will see an analysis of your system state.
1. Create a Project
2. Set up the SDK
Prepare folder for memfault-firmware-sdk & port
The memfault-firmware-sdk
is a self-contained C SDK you will need to include
into your project.
Create a folder to hold memfault-firmware-sdk
as well as the configuration and
porting files to your platform.
cd ${YOUR_PROJECT_DIR}
mkdir -p third_party/memfault
cd third_party/memfault
# Add memfault repo as submodule, subtree, or copy in as source directly
git submodule add https://github.com/memfault/memfault-firmware-sdk.git memfault-firmware-sdk
cp memfault-firmware-sdk/ports/templates/* .
When you are done, you should have the following directory structure in your project:
memfault/
//...
├── memfault-firmware-sdk (submodule)
| # Files where port / glue layer to your platform will be implemented
├── memfault_platform_port.c
|
| # Configuration Headers
├── memfault_metrics_heartbeat_config.def
└── memfault_trace_reason_user_config.def
└── memfault_platform_log_config.h
└── memfault_platform_config.h
Add Sources to Build System
Based on the build system you are using, expand the appropriate tab below and follow the steps to add the sources to your target
- Make
- CMake
- Other
MEMFAULT_PORT_ROOT := <YOUR_PROJECT_ROOT>/third_party/memfault
MEMFAULT_SDK_ROOT := $(MEMFAULT_PORT_ROOT)/memfault-firmware-sdk
MEMFAULT_COMPONENTS := core util panics metrics
include $(MEMFAULT_SDK_ROOT)/makefiles/MemfaultWorker.mk
<YOUR_SRC_FILES> += \
$(MEMFAULT_COMPONENTS_SRCS) \
$(MEMFAULT_PORT_ROOT)/memfault_platform_port.c
<YOUR_INCLUDE_PATHS> += \
$(MEMFAULT_COMPONENTS_INC_FOLDERS) \
$(MEMFAULT_SDK_ROOT)/ports/include \
$(MEMFAULT_PORT_ROOT)
Be sure to update YOUR_SRC_FILES
, YOUR_INCLUDE_PATHS
, and
YOUR_PROJECT_ROOT
accordingly for your system above!
set(MEMFAULT_PORT_ROOT <YOUR_PROJECT_ROOT>/third_party/memfault)
set(MEMFAULT_SDK_ROOT ${MEMFAULT_PORT_ROOT}/memfault-firmware-sdk)
list(APPEND MEMFAULT_COMPONENTS core util panics metrics)
include(${MEMFAULT_SDK_ROOT}/cmake/Memfault.cmake)
memfault_library(${MEMFAULT_SDK_ROOT} MEMFAULT_COMPONENTS
MEMFAULT_COMPONENTS_SRCS MEMFAULT_COMPONENTS_INC_FOLDERS)
# Add the following to your target sources:
# ${MEMFAULT_COMPONENTS_SRCS}
# ${MEMFAULT_PORT_ROOT}/memfault_platform_port.c
#
# Add the following to your target includes
# ${MEMFAULT_COMPONENTS_INC_FOLDERS}
# ${MEMFAULT_SDK_ROOT}/ports/include
# ${MEMFAULT_PORT_ROOT}
Be sure to update YOUR_PROJECT_ROOT
, add ${MEMFAULT_COMPONENTS_SRCS}
to your
target sources and ${MEMFAULT_COMPONENTS_INC_FOLDERS}
to your target includes
accordingly
- add
$MEMFAULT_FIRMWARE_SDK/components/include
to the include paths for your project - add
$MEMFAULT_FIRMWARE_SDK/ports/include
to the include paths for your project - add the sources under
$MEMFAULT_FIRMWARE_SDK/components/[core, util, panics, metrics]/src/**/*.c
to your project - add
third_party/memfault/memfault_platform_port.c
sources to project - add
third_party/memfault/
to the include paths for your project
When using Eclipse as your build system, folders can be opted out from a build by right clicking on the folder and selecting "Resource Configuration" -> "Exclude from Build".
Core Dependencies
Open the
memfault_platform_port.c
copied into your third_party/memfault
folder and fill out the stub
implementations accordingly.
Initialize Memfault Subsystem On Bootup
From your main routine, add a call to memfault_platform_boot()
prior to the
startup of an RTOS or baremetal while loop.
#include "memfault/components.h"
// ...
int main(void) {
// ...
memfault_platform_boot();
// ...
}
Reboot Tracking Dependencies
Memfault has a module for tracking and reporting what resets are taking place on your platform.
- nRF5 SDK
- STM32
- NXP S32 SDK
- EFM/EFR (Gecko SDK)
- NXP RW610/611/612
- SiLabs SiWx91x
- Other
Add the following file to your build system:
${MEMFAULT_SDK_ROOT}/ports/nrf5_sdk/resetreas_reboot_tracking.c
STM32CubeF4
Add the following file to your build system:
${MEMFAULT_SDK_ROOT}/ports/stm32cube/f4/rcc_reboot_tracking.c
STM32CubeL4
Add the following file to your build system:
${MEMFAULT_SDK_ROOT}/ports/stm32cube/l4/rcc_reboot_tracking.c
STM32CubeWB
Add the following file to your build system:
${MEMFAULT_SDK_ROOT}/ports/stm32cube/wb/rcc_reboot_tracking.c
Allocate noinit region & Collect Reboot Info
Add the following to your memfault_platform_port.c
//! @file memfault_platform_port.c
MEMFAULT_PUT_IN_SECTION(".noinit.mflt_reboot_tracking")
static uint8_t s_reboot_tracking[MEMFAULT_REBOOT_TRACKING_REGION_SIZE];
void memfault_platform_reboot_tracking_boot(void) {
sResetBootupInfo reset_info = { 0 };
memfault_reboot_reason_get(&reset_info);
memfault_reboot_tracking_boot(s_reboot_tracking, &reset_info);
}
It's expected that s_reboot_tracking
is placed in "noinit" RAM. That is, a
region of RAM not initialized on bootup or used by your bootloaders. This can be
achieved by adding a "noinit" section to your linker script.
GNU GCC Example
Add the following to your .ld
file:
.noinit (NOLOAD): { KEEP(*(*.noinit.mflt*)) } >RAM
ARM MDK Example
Add the following to your .sct
file:
; Within previously defined Load Region, modify NOINIT_RAM address and length as necessary
NOINIT_RAM 0x20010000 UNINIT 0x00000200 { ;no init section
*(.noinit.mflt*)
}
IAR Example
Add the following to your .icf
file:
do not initialize
{
section .noinit,
section .stack,
section .heap,
/* Add line to a do not initialize directive */
rw section .noinit.mflt*,
};
Add the following file to your build system:
${MEMFAULT_SDK_ROOT}/ports/s32sdk/rcm_reboot_tracking.c
Allocate noinit region & Collect Reboot Info
Add the following to your memfault_platform_port.c
//! @file memfault_platform_port.c
MEMFAULT_PUT_IN_SECTION(".noinit.mflt_reboot_tracking")
static uint8_t s_reboot_tracking[MEMFAULT_REBOOT_TRACKING_REGION_SIZE];
void memfault_platform_reboot_tracking_boot(void) {
sResetBootupInfo reset_info = { 0 };
memfault_reboot_reason_get(&reset_info);
memfault_reboot_tracking_boot(s_reboot_tracking, &reset_info);
}
It's expected that s_reboot_tracking
is placed in "noinit" RAM. That is, a
region of RAM not initialized on bootup or used by your bootloaders. This can be
achieved by adding a "noinit" section to your linker script.
GNU GCC Example
Add the following to your .ld
file:
.noinit (NOLOAD): { KEEP(*(*.noinit.mflt*)) } >RAM
ARM MDK Example
Add the following to your .sct
file:
; Within previously defined Load Region, modify NOINIT_RAM address and length as necessary
NOINIT_RAM 0x20010000 UNINIT 0x00000200 { ;no init section
*(.noinit.mflt*)
}
IAR Example
Add the following to your .icf
file:
do not initialize
{
section .noinit,
section .stack,
section .heap,
/* Add line to a do not initialize directive */
rw section .noinit.mflt*,
};