blob: d6ad2ffc94df26d1029b8b946b35a7fb4a5b0a7d [file] [log] [blame]
//! @file
//!
//! Copyright (c) Memfault, Inc.
//! See LICENSE for details
//!
//! @brief
//! Command definitions for the minimal shell/console implementation.
#include <stddef.h>
#include <string.h>
#include "memfault/core/compiler.h"
#include "memfault/core/data_export.h"
#include "memfault/core/debug_log.h"
#include "memfault/core/math.h"
#include "memfault/core/self_test.h"
#include "memfault/demo/cli.h"
#include "memfault/demo/shell_commands.h"
#include "memfault/metrics/metrics.h"
static int prv_panics_component_required(void) {
MEMFAULT_LOG_RAW("Disabled. panics component integration required");
return -1;
}
MEMFAULT_WEAK int memfault_demo_cli_cmd_get_core(MEMFAULT_UNUSED int argc,
MEMFAULT_UNUSED char *argv[]) {
return prv_panics_component_required();
}
MEMFAULT_WEAK int memfault_demo_cli_cmd_clear_core(MEMFAULT_UNUSED int argc,
MEMFAULT_UNUSED char *argv[]) {
return prv_panics_component_required();
}
MEMFAULT_WEAK int memfault_demo_cli_cmd_crash(MEMFAULT_UNUSED int argc,
MEMFAULT_UNUSED char *argv[]) {
return prv_panics_component_required();
}
int memfault_demo_cli_cmd_export(MEMFAULT_UNUSED int argc, MEMFAULT_UNUSED char *argv[]) {
memfault_data_export_dump_chunks();
return 0;
}
// Provide weak implementations in the case where the metrics component is not enabled
MEMFAULT_WEAK void memfault_metrics_heartbeat_debug_print(void) {
MEMFAULT_LOG_RAW("Disabled. metrics component integration required");
}
MEMFAULT_WEAK void memfault_metrics_heartbeat_debug_trigger(void) {
MEMFAULT_LOG_RAW("Disabled. metrics component integration required");
}
MEMFAULT_WEAK void memfault_metrics_all_sessions_debug_print(void) {
MEMFAULT_LOG_RAW("Disabled. metrics component integration required");
}
static int memfault_demo_cli_cmd_metrics_dump(int argc, char *argv[]) {
if (argc < 2) {
MEMFAULT_LOG_RAW("Enter 'heartbeat' or 'sessions'");
return 0;
}
if (!strncmp(argv[1], "sessions", sizeof("sessions"))) {
memfault_metrics_all_sessions_debug_print();
} else if (!strncmp(argv[1], "heartbeat", sizeof("heartbeat"))) {
memfault_metrics_heartbeat_debug_print();
} else {
MEMFAULT_LOG_RAW("Unknown option. Enter 'heartbeat' or 'sessions'");
return 0;
}
return 0;
}
int memfault_demo_cli_cmd_heartbeat(MEMFAULT_UNUSED int argc, MEMFAULT_UNUSED char *argv[]) {
memfault_metrics_heartbeat_debug_trigger();
return 0;
}
#if MEMFAULT_DEMO_CLI_SELF_TEST
int memfault_demo_cli_cmd_self_test(int argc, char *argv[]) {
uint32_t run_flags = kMemfaultSelfTestFlag_Default;
// If we got an arg, translate to a test flag
if (argc >= 2) {
run_flags = memfault_self_test_arg_to_flag(argv[1]);
}
return memfault_self_test_run(run_flags);
}
#endif
static const sMemfaultShellCommand s_memfault_shell_commands[] = {
{ "clear_core", memfault_demo_cli_cmd_clear_core, "Clear an existing coredump" },
{ "drain_chunks", memfault_demo_drain_chunk_data,
"Flushes queued Memfault data. To upload data see https://mflt.io/posting-chunks-with-gdb" },
{ "export", memfault_demo_cli_cmd_export,
"Export base64-encoded chunks. To upload data see https://mflt.io/chunk-data-export" },
{ "get_core", memfault_demo_cli_cmd_get_core, "Get coredump info" },
{ "get_device_info", memfault_demo_cli_cmd_get_device_info, "Get device info" },
{ "coredump_size", memfault_demo_cli_cmd_coredump_size, "Print the coredump storage capacity" },
{ "heartbeat", memfault_demo_cli_cmd_heartbeat, "Trigger a heartbeat" },
{ "metrics_dump", memfault_demo_cli_cmd_metrics_dump,
"Dump current heartbeat or session metrics" },
//
// Test commands for validating SDK functionality: https://mflt.io/mcu-test-commands
//
{ "test_assert", memfault_demo_cli_cmd_assert, "Trigger memfault assert" },
{ "test_cassert", memfault_demo_cli_cmd_cassert, "Trigger C assert" },
#if MEMFAULT_COMPILER_ARM_CORTEX_M
{ "test_busfault", memfault_demo_cli_cmd_busfault, "Trigger a busfault" },
{ "test_hardfault", memfault_demo_cli_cmd_hardfault, "Trigger a hardfault" },
{ "test_memmanage", memfault_demo_cli_cmd_memmanage, "Trigger a memory management fault" },
{ "test_usagefault", memfault_demo_cli_cmd_usagefault, "Trigger a usage fault" },
#endif
#if MEMFAULT_COMPILER_ARM_V7_A_R
{ "test_dataabort", memfault_demo_cli_cmd_dataabort, "Trigger a data abort" },
{ "test_prefetchabort", memfault_demo_cli_cmd_prefetchabort, "Trigger a prefetch abort" },
#endif
{ "test_log", memfault_demo_cli_cmd_test_log, "Writes test logs to log buffer" },
{ "test_log_capture", memfault_demo_cli_cmd_trigger_logs,
"Trigger capture of current log buffer contents" },
{ "test_reboot", memfault_demo_cli_cmd_system_reboot,
"Force system reset and track it with a trace event" },
{ "test_trace", memfault_demo_cli_cmd_trace_event_capture, "Capture an example trace event" },
#if MEMFAULT_DEMO_CLI_SELF_TEST
{ "self_test", memfault_demo_cli_cmd_self_test,
"Run a self test to check integration with the SDK" },
#endif
#if MEMFAULT_DEMO_CLI_WATCHDOG
{ "wdog_enable", memfault_demo_cli_cmd_software_watchdog_enable, "Enable the software watchdog" },
{ "wdog_disable", memfault_demo_cli_cmd_software_watchdog_disable,
"Disable the software watchdog" },
{ "wdog_update", memfault_demo_cli_cmd_software_watchdog_update_timeout,
"Update the software watchdog timeout" },
#endif
{ "help", memfault_shell_help_handler, "Lists all commands" },
};
// Note: Declared as weak so an end user can override the command table
MEMFAULT_WEAK const sMemfaultShellCommand *const g_memfault_shell_commands =
s_memfault_shell_commands;
MEMFAULT_WEAK const size_t g_memfault_num_shell_commands =
MEMFAULT_ARRAY_SIZE(s_memfault_shell_commands);