Skip to main content

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:

  1. The console component is required to add the demo CLI. Most projects include all components by default. If your project specifies a COMPONENTS list, add the console component to the list
  2. Set the Kconfig CONFIG_MEMFAULT_CLI_ENABLED through default values, or in your sdkconfig.default file
  3. 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 assert
  • crash 1 - triggers a hard fault due to a bad instruction fetch
  • crash 2 - triggers a hard fault due to a unaligned access
  • crash 3 - triggers an assert deep in a callstack
  • crash 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.

note

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 via ESP_ERROR_CHECK(10)
  • esp_crash 2 - triggers a crash in a timer ISR
  • esp_crash 3 - triggers a crash through deep recursive callstack with MEMFAULT_ASSERT_RECORD()
  • esp_crash 4 - triggers a crash in a deep regular callstack via MEMFAULT_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>
note

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.

note

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:

Data can be exported and cleared with: