Using the Demo CLI
Most reference implementations of the Memfault embedded SDK include a Command Line Interface (CLI) demo app. The demo CLI lets you explore features of the SDK components before integrating the SDK into your product. You might also find it helpful to adapt the CLI to your product and use it to exercise your own Memfault implementation.
This guide explains the commands available in the demo CLI and how to interpret their output.
Enabling the Demo CLI
On some platforms with integrated Memfault support (Zephyr or ESP-IDF), the demo component is enabled automatically, but will have no effect on the target if the system shell is not enabled. On unhosted platforms, see the instructions below for enabling the Demo CLI.
To include the Demo component in your project, the demo
sources will need to
be added. Select the tab below that applies to your project.
- Make
- CMake
- Other/IDE
Include the demo
component in the MEMFAULT_COMPONENTS
list:
MEMFAULT_COMPONENTS := core util panics metrics demo
Include the demo
component in the MEMFAULT_COMPONENTS
list:
include(${MEMFAULT_SDK_ROOT}/cmake/Memfault.cmake)
list(APPEND MEMFAULT_COMPONENTS core util panics metrics demo)
memfault_library(${MEMFAULT_SDK_ROOT} MEMFAULT_COMPONENTS
MEMFAULT_COMPONENTS_SRCS MEMFAULT_COMPONENTS_INC_FOLDERS)
The demo
component files are located here:
- sources:
memfault-firmware-sdk/components/demo/
- includes:
memfault-firmware-sdk/components/include/memfault/demo/
Add the source files to the project, and add the include directory to the preprocessor search directories.
The Demo component has an additional dependency that must be implemented:
memfault_platform_log_raw()
. An example implementation can be found below,
which uses printf
as the output backend.
#include <stdarg.h>
#include <stdio.h>
void memfault_platform_log_raw(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
printf("\n");
va_end(args);
}
Running a Command
The CLI displays a prompt to indicate it is ready to accept a command. To see if the CLI is running, press enter and the prompt should be printed:
mflt>
To run a command, type its name and press enter. Try the help
command to get
started.
Command Reference
help
The help
command shows all available commands. Type help
and press enter:
mflt> help
get_device_info: Get device info
crash: Trigger a crash
get_core: Get coredump info
clear_core: Clear an existing coredump
trace: Capture trace event
export: Get next Memfault data chunk to send and print as a curl command
help: Lists all commands
mflt>
Some reference implementations have more commands than others. For example, some
targets have network connectivity and can send data directly to the Memfault
cloud via the post_chunk
command. Devices without this ability
will not have that command.
get_device_info
The get_device_info
command shows the information configured in the reference
implementation's memfault_platform_get_device_info()
:
mflt> get_device_info
MFLT: [INFO] S/N: 123456789012345678901234
MFLT: [INFO] SW type: NAME-main
MFLT: [INFO] SW version: 1.0.0
MFLT: [INFO] HW version: NAME-proto
mflt>
This information is sent to Memfault with any communications to identify the device and the firmware it is running.
ℹ️ Remember to increment the software version (SW version:
above) each time
you create a new build. Memfault uses the software version to associate a
coredump with its symbols. If you upload a coredump from a new build of the
firmware without updating the software version, the old symbols may be used and
the analysis on Memfault may not make sense.
crash
The crash
command causes the target the crash in various ways:
crash 0
or justcrash
causes a crash byMEMFAULT_ASSERT(0)
crash 1
causes a crash by jumping to a non-executable address (0xbadcafe
)crash 2
causes a crash by performing an unaligned memory store
The crash will be intercepted by the fault handler in the Memfault panics
component, a coredump will be generated and stored, and then the device
rebooted:
mflt> crash
MFLT: [INFO] Memfault demo app started...
mflt>
The demo CLI prints Memfault demo app started...
whenever the device reboots.
If you do not see this message and the prompt return, then something may have
gone wrong in the fault handler. Another possibility is that a debugger is
attached and it is sitting on a breakpoint. The fault handler in most reference
implementations will break into the debugger if one is attached. In GDB, you
should be able to use stepi
to resume, but see the README
for the specific
reference implementation you are using in case it has other instructions.
Once the prompt has returned, the storage can be checked with the
get_core
command. It can then be cleared with
clear_core
or read out of the coredump storage with
export
.
⚠️ Once a coredump has been stored in the coredump storage, it will remain there
until either storage is cleared (clear_core
command) or read
out (export
command). If you crash
again without doing one of
these, saving the coredump will fail silently. The device will still crash and
reset but the existing coredump will not be overwritten.
get_core
The get_core
command displays the state of the coredump storage.
If a coredump is present in the coredump storage:
mflt> get_core
MFLT: [INFO] Has coredump with size: 20224
mflt>
If a coredump is not present:
mflt> get_core
MFLT: [INFO] No coredump present!
mflt>
Running get_core
only displays information. It does not affect the state of
the coredump storage.
clear_core
The clear_core
command unconditionally invalidates the coredump storage so
that a new coredump can be stored:
mflt> clear_core
MFLT: [INFO] Invalidating coredump
mflt>
The clear_core
command will show the same output regardless of whether a
coredump was present in the coredump storage or not.
trace
The trace
command captures a trace event and writes it to
the event storage.
mflt> trace
mflt>
Once a trace has been captured, it can be read out of the event storage with the
export
command.
⚠️ The event storage is completely separate from the coredump storage. The
commands get_core
and clear_core
work only on the coredump storage. There
are no equivalents for the event storage.
export
The export
command reads out all data from both the coredump storage and the
event storage. It then formats this data into a base64-encoded
chunk that can be sent to the Memfault
cloud using one of the
strategies described here.
# example export command output
mflt> export
MC:CAKnAgIDAQpqemVwaHlyLWFwcAltMS4wLjArZGJkZWI0OAZucWVtdV9jb3J0ZXhfbTMLRvknGqz1fwSiAQAFAMQ5:
MC:SE8CpwIBAwEKanplcGh5ci1hcHAJbTEuMC4wK2RiZGViNDgGbnFlbXVfY29ydGV4X20zC0b5Jxqs9X8EoQGIAAEBGQyIGefcGfWnGQ+0GQw=:
⚠️ The export
command has the side effect of clearing the data. After the
packetizer consumes the coredump storage
and the event storage, they will both be cleared and ready for new data.
⚠️ If the upload succeeds but you don't see the data processed on Memfault, go to the Issues page and click on "Queue Status" to see the status of recent uploads. You probably need to upload the symbols.
post_chunk
The post_chunk
command is available on targets with direct network
connectivity:
mflt> post_chunk
Posting data to the Memfault cloud...
All data has been posted!
mflt>
It will read out all data from both the coredump storage and event storage and
then send the data directly to the Memfault cloud. The target must already be
configured on a network and be able to make an HTTPS
connection to the
Memfault cloud servers. A valid Memfault project key must also be configured.
See the instructions in the reference implementation for how to do this.
⚠️ The post_chunk
command has the side effect of clearing the data. After the
packetizer consumes the coredump storage
and the event storage, they will both be cleared and ready for new data.
⚠️ If the upload succeeds but you don't see the data processed on Memfault, you probably need to upload the symbols.
SDK Components
This list summarizes which demo CLI commands are used to test each SDK component:
- Core
- Panics
- Trace Events
Implementation Notes
The demo CLI itself is implemented as two components:
demo/memfault_demo_shell
implements the console. It handles character input and output, displaying the prompt, and dispatching the command to a C function inmemfault_demo_cli
that performs it. The demo shell is not used on all reference implementations. Some target platforms have a similar shell toolkit built-in. For those platforms, the built-in shell maybe used to callmemfault_demo_cli
functions directly.demo/memfault_demo_cli
implements the actual demo. It has one function for each command on the CLI. Each function typically calls one function in the SDK, checks the result, and formats the output.
Using Invoke Commands in the SDK
The CLI runs on the embedded device itself and communicates with a host computer
over a communications interface. The interface varies depending on what is
available on the target but it will commonly be serial (UART), Segger RTT, or
semihosting. The README
file for the example implementations explains the
interface and any steps needed to wire it up. The console works the same
regardless of the interface used.
The CLI is started with an Invoke command similar to this:
$ invoke NAME.console
Replace NAME
with the name of the reference implementation (eg mbed
). The
README
file for the implementation will give the exact command. If the
invoke
command does not halt with an error message, the console is active and
can accept commands.
ℹ️ The invoke
command does more than just pass through characters as a
terminal would. It actively listens to the connection and provides a special
feature used with the export
command.
If you are running the demo CLI via the Invoke wrapper,you should see this prompt:
Invoke CLI wrapper detected 'export' call
Would you like to run the command displayed above? [y/n]
The above prompt comes from your computer, not from the demo CLI running on the
target. The Invoke wrapper monitors all output from the demo CLI and when it
detects the output from the export
command, it interrupts the session and
offers to run the curl
command automatically.
After you accept (or decline) to run the curl
command, the Invoke wrapper will
return you to your session with the demo CLI. If you don't see the mflt>
prompt, press enter and it should appear:
mflt>