Demo CLI for ESP-IDF
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 built for ESP-IDF and how to interpret their output.
Enabling the Demo CLI
Here are the steps to confirm the demo CLI is part of your build:
- The
console
component is required to add the demo CLI. Most projects include all components by default. If your project specifies aCOMPONENTS
list, add theconsole
component to the list - Set the Kconfig
CONFIG_MEMFAULT_CLI_ENABLED
through default values, or in yoursdkconfig.default
file - Check your build's generated
sdkconfig
file to confirm the correct configuration.
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:
esp32>
To run a command, simply type its name and press enter.
Command Reference
get_device_info
The get_device_info
command shows the information configured in the reference
implementation's memfault_platform_get_device_info()
:
esp32> get_device_info
I (55239) mflt: S/N: 30AEA44AFF28
I (55239) mflt: SW type: esp32-main
I (55239) mflt: SW version: 1.0.0-dev
I (55239) mflt: HW version: esp32-proto
This information is sent to Memfault with any communications to identify the device and the firmware it is running.
crash
The crash
command followed by a crash type selection will trigger a fault.
crash 0
- triggers an assertcrash 1
- triggers a hard fault due to a bad instruction fetchcrash 2
- triggers a hard fault due to a unaligned accesscrash 3
- triggers an assert deep in a callstackcrash 4
- triggers a software watchdog
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 reboots.
Typically, Build ID and device info will be printed on boot, making it easy to
tell that we have rebooted. For example:
esp32> crash 0
abort() was called at PC 0x4200a831 on core 0
Core 0 register dump:
MEPC : 0x403830a4 RA : 0x40381b86 SP : 0x3fc9df30 GP : 0x3fc91800
TP : 0x3fc73084 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
S0/FP : 0x3fc9df7c S1 : 0x3fc9df60 A0 : 0x3fc9df7c A1 : 0x40386c36
A2 : 0x00008001 A3 : 0x00008001 A4 : 0x00000001 A5 : 0x3fc9a000
A6 : 0x7a797877 A7 : 0x76757473 S2 : 0x4203a51a S3 : 0x3fcb1bbc
S4 : 0x00000001 S5 : 0x3fca1948 S6 : 0x3c0b6000 S7 : 0x00000000
S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
MSTATUS : 0x00001801 MTVEC : 0x40380001 MCAUSE : 0x00000007 MTVAL : 0x00000000
MHARTID : 0x00000000
Stack memory:
...
Rebooting...
If you do not see these messages and the prompt return, nor any other
indications that the system reset, 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 new coredump will not be saved.
esp_crash
The esp_crash
command followed by a crash type selection triggers a timer ISR
crash.
esp_crash 0
- triggers a crash viaESP_ERROR_CHECK(10)
esp_crash 2
- triggers a crash in a timer ISResp_crash 3
- triggers a crash through deep recursive callstack withMEMFAULT_ASSERT_RECORD()
esp_crash 4
- triggers a crash in a deep regular callstack viaMEMFAULT_ASSERT_RECORD()
esp32> esp_crash 4
abort() was called at PC 0x4200a843 on core 0
Core 0 register dump:
MEPC : 0x403830a4 RA : 0x40381b86 SP : 0x3fc9de30 GP : 0x3fc91800
TP : 0x3fc73084 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
S0/FP : 0x3fc9de7c S1 : 0x3fc9de60 A0 : 0x3fc9de7c A1 : 0x40386c36
A2 : 0x00008001 A3 : 0x00008001 A4 : 0x00000001 A5 : 0x3fc9a000
A6 : 0x7a797877 A7 : 0x76757473 S2 : 0x3fc9e030 S3 : 0x3fcabb50
S4 : 0x3fc9a000 S5 : 0x3fca1948 S6 : 0x3c0b6000 S7 : 0x00000000
S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
MSTATUS : 0x00001801 MTVEC : 0x40380001 MCAUSE : 0x00000007 MTVAL : 0x00000000
MHARTID : 0x00000000
Stack memory:
...
Rebooting...
assert
For more options for asserts, use the assert
command followed by an assert
type selection.
assert 1
- triggers a standard C assert()assert 2
- triggers a MEMFAULT_ASSERT()assert 3
- triggers a ESP_ERROR_CHECK(-1)
esp32> assert 1
assert failed: prv_esp32_assert_example memfault_platform_demo_cli_cmds.c:157 (0)
Core 0 register dump:
MEPC : 0x403830a4 RA : 0x40381b86 SP : 0x3fc9dea0 GP : 0x3fc91800
TP : 0x3fc73084 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130
S0/FP : 0x3fc9df08 S1 : 0x3fc9e021 A0 : 0x3fc9df08 A1 : 0x3fc9de88
A2 : 0xffffffff A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3fc9a000
A6 : 0x7a797877 A7 : 0x76757473 S2 : 0x00000076 S3 : 0x3fc9df08
S4 : 0x3fc9df08 S5 : 0x3c0b7bb8 S6 : 0x3c0b6000 S7 : 0x00000000
S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938
MSTATUS : 0x00001801 MTVEC : 0x40380001 MCAUSE : 0x00000007 MTVAL : 0x00000000
MHARTID : 0x00000000
Stack memory:
...
Rebooting...
get_core
The get_core
command displays the state of the coredump storage.
If a coredump is present in the coredump storage:
esp32> get_core
I (77840) mflt: Has coredump with size: 768
esp32>
If a coredump is not present:
esp32> get_core
I (77840) mflt: No coredump present!
esp32>
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:
esp32> clear_core
I (77840) mflt: Invalidating coredump
esp32>
The clear_core
command will show the same output regardless of whether a
coredump was present in the coredump storage or not.
coredump_size
The coredump_size
command prints the coredump storage capacity and the
capacity required.
esp32> coredump_size
I (58318) mflt: Coredump size: 329216, capacity: 262144
esp32>
If the size required is larger than the capacity, a partial coredump will be collected. To either limit how much you collect or increase the storage capacity, refer to the Coredump Collection guide.
heartbeat_dump
The heartbeat_dump
command will print out the current values of the Heartbeat
metrics. If a value has not been written to a metric in the current Heartbeat
window, it's value will be shown as null
.
I (86488) mflt: Heartbeat keys/values:
I (86488) mflt: MemfaultSdkMetric_IntervalMs: 86156
I (86488) mflt: MemfaultSdkMetric_UnexpectedRebootCount: 8
I (86498) mflt: sync_successful: 1
I (86498) mflt: sync_failure: null
I (86498) mflt: sync_memfault_successful: 1
I (86518) mflt: sync_memfault_failure: null
I (86518) mflt: connectivity_connected_time_ms: 85784
I (86528) mflt: connectivity_expected_time_ms: 85859
I (86528) mflt: operational_hours: null
I (86538) mflt: operational_crashfree_hours: null
I (86538) mflt: tcp_tx_count: null
I (86548) mflt: tcp_rx_count: null
I (86548) mflt: tcp_drop_count: null
esp32>
The Heartbeat metrics will only reset after a Heartbeat interval has expired or
by running the heartbeat
command.
heartbeat
The heartbeat
command captures the current Heartbeat, writes it to event
storage, and resets the running Heartbeat metrics.
esp32> Heartbeat
esp32>
The current values of the Heartbeat metrics may or may not get printed like
above depending on if memfault_metrics_heartbeat_debug_print()
is being called
in memfault_metrics_heartbeat_collect_data()
.
memfault_metrics_heartbeat_collect_data()
is a function that can be overridden
with a user definition if they want to set certain metric values at the end of a
Heartbeat right before collection.
test_log
The test_log
command writes test logs to Memfault's logging
buffer.
esp32> test_log
Raw log!
I (155728) mflt: Info log!
W (155728) mflt: Warning log!
E (155728) mflt: Error log!
esp32>
trigger_logs
The trigger_logs
command captures the current log buffer contents, so they
will be ready once data is exported.
esp32> trigger_logs
esp32>
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
esp32> export
MC:CAKnAgIDAQpqemVwaHlyLWFwcAltMS4wLjArZGJkZWI0OAZucWVtdV9jb3J0ZXhfbTMLRvknGqz1fwSiAQAFAMQ5:
MC:SE8CpwIBAwEKanplcGh5ci1hcHAJbTEuMC4wK2RiZGViNDgGbnFlbXVfY29ydGV4X20zC0b5Jxqs9X8EoQGIAAEBGQyIGefcGfWnGQ+0GQw=:
esp32>
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 Processing Log under the "Integration Hub" sub-menu. The Processing Log contains details on what data has been received and processed by Memfault, as well as any error that may have occurred. Note that you need to upload the symbols to get a complete analysis of uploaded coredumps.
post_chunks
The post_chunks
command is available on targets with direct network
connectivity. When data is available, the console will print:
esp32> post_chunks
I (271938) mflt: Result: 0
esp32>
and when data is not available:
esp32> post_chunks
I (374728) mflt: No new data found
esp32>
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_chunks
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.
memfault_ota_check
The memfault_ota_check
command checks if a payload is available. To initiate
the OTA, call memfault_ota_perform
.
When up-to-date, the device will print:
esp32> memfault_ota_check
I (467508) mflt: Checking for OTA Update
I (467908) mflt: Up to date!
esp32>
and when an update is available:
esp32> memfault_ota_check
I (13584) mflt: Checking for OTA Update
I (14364) mflt: Update available!
esp32>
memfault_ota_perform
The memfault_ota_perform
command queries Memfault for a OTA update payload
then pull the payload if one is available. Once the payload is downloaded
completely, the system will reboot with the new image.
esp32> memfault_ota_perform
I (18454) mflt: Checking for OTA Update
I (19374) mflt: Starting OTA download ...
I (20394) esp_https_ota: Starting OTA...
I (20394) esp_https_ota: Writing to partition subtype 16 at offset 0x1e0000
I (72774) esp_image: segment 0: paddr=001e0020 vaddr=3c0b0020 size=2ba60h (178784) map
I (72794) esp_image: segment 1: paddr=0020ba88 vaddr=3fc91000 size=02a4ch ( 10828)
I (72804) esp_image: segment 2: paddr=0020e4dc vaddr=40380000 size=01b3ch ( 6972)
I (72814) esp_image: segment 3: paddr=00210020 vaddr=42000020 size=a72bch (684732) map
I (72904) esp_image: segment 4: paddr=002b72e4 vaddr=40381b3c size=0f460h ( 62560)
I (72914) esp_image: segment 0: paddr=001e0020 vaddr=3c0b0020 size=2ba60h (178784) map
I (72944) esp_image: segment 1: paddr=0020ba88 vaddr=3fc91000 size=02a4ch ( 10828)
I (72944) esp_image: segment 2: paddr=0020e4dc vaddr=40380000 size=01b3ch ( 6972)
I (72954) esp_image: segment 3: paddr=00210020 vaddr=42000020 size=a72bch (684732) map
I (73044) esp_image: segment 4: paddr=002b72e4 vaddr=40381b3c size=0f460h ( 62560)
I (73134) mflt: OTA Update Complete, Rebooting System
memfault_self_test
The self_test
command runs tests on the most important subsystems of Memfault
to validate proper integration of the SDK.
SDK Components
This list summarizes which demo CLI commands are used to test each SDK component:
- Core
- Panics
crash
for crashesget_core
clear_core
- Logs
- Metrics
- OTA
Data can be exported and cleared with: