From ecd7c23daa0c8fb26f73cff8ea3aafad9f22b8a7 Mon Sep 17 00:00:00 2001 From: Alexander Wachter Date: Tue, 21 Sep 2021 09:01:04 +0200 Subject: [PATCH] drivers: hwinfo: shell: Add reset cause shell command This commit adds shell commands for the reset cause API - show: show the persistent reset cause - clear: clear the persistent reset cause - supported: list all supported reset causes Signed-off-by: Alexander Wachter --- drivers/hwinfo/hwinfo_shell.c | 141 ++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/drivers/hwinfo/hwinfo_shell.c b/drivers/hwinfo/hwinfo_shell.c index a7289eb76d1..72ef4aaf393 100644 --- a/drivers/hwinfo/hwinfo_shell.c +++ b/drivers/hwinfo/hwinfo_shell.c @@ -38,8 +38,149 @@ static int cmd_get_device_id(const struct shell *sh, size_t argc, char **argv) return 0; } +static inline const char *cause_to_string(uint32_t cause) +{ + switch (cause) { + case RESET_PIN: + return "pin"; + + case RESET_SOFTWARE: + return "software"; + + case RESET_BROWNOUT: + return "brownout"; + + case RESET_POR: + return "power-on reset"; + + case RESET_WATCHDOG: + return "watchdog"; + + case RESET_DEBUG: + return "debug"; + + case RESET_SECURITY: + return "security"; + + case RESET_LOW_POWER_WAKE: + return "low power wake-up"; + + case RESET_CPU_LOCKUP: + return "CPU lockup"; + + case RESET_PARITY: + return "parity error"; + + case RESET_PLL: + return "PLL error"; + + case RESET_CLOCK: + return "clock"; + + default: + return "unknown"; + } +} + +static void print_all_reset_causes(const struct shell *sh, uint32_t cause) +{ + for (uint32_t cause_mask = 1; cause_mask; cause_mask <<= 1) { + if (cause & cause_mask) { + shell_print(sh, "- %s", + cause_to_string(cause & cause_mask)); + } + } +} + +static int cmd_show_reset_cause(const struct shell *sh, size_t argc, + char **argv) +{ + int res; + uint32_t cause; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + res = hwinfo_get_reset_cause(&cause); + if (res == -ENOTSUP) { + shell_error(sh, "Not supported by hardware"); + return res; + } else if (res != 0) { + shell_error(sh, "Error reading the cause [%d]", res); + return res; + } + + if (cause != 0) { + shell_print(sh, "reset caused by:"); + print_all_reset_causes(sh, cause); + } else { + shell_print(sh, "No reset cause set"); + } + + return 0; +} + +static int cmd_clear_reset_cause(const struct shell *sh, size_t argc, + char **argv) +{ + int res; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + res = hwinfo_clear_reset_cause(); + if (res == -ENOTSUP) { + shell_error(sh, "Not supported by hardware"); + } else if (res != 0) { + shell_error(sh, "Error clearing the reset causes [%d]", res); + return res; + } + + return 0; +} + +static int cmd_supported_reset_cause(const struct shell *sh, size_t argc, + char **argv) +{ + uint32_t cause; + int res; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + res = hwinfo_get_supported_reset_cause(&cause); + if (res == -ENOTSUP) { + shell_error(sh, "Not supported by hardware"); + } else if (res != 0) { + shell_error(sh, "Could not get the supported reset causes [%d]", res); + return res; + } + + if (cause != 0) { + shell_print(sh, "supported reset causes:"); + print_all_reset_causes(sh, cause); + } else { + shell_print(sh, "No causes supporte"); + } + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_reset_cause, + SHELL_CMD_ARG(show, NULL, "Show persistent reset causes", + cmd_show_reset_cause, 1, 0), + SHELL_CMD_ARG(clear, NULL, "Clear all persistent reset causes", + cmd_clear_reset_cause, 1, 0), + SHELL_CMD_ARG(supported, NULL, + "Get a list of all supported reset causes", + cmd_supported_reset_cause, 1, 0), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); + SHELL_STATIC_SUBCMD_SET_CREATE(sub_hwinfo, SHELL_CMD_ARG(devid, NULL, "Show device id", cmd_get_device_id, 1, 0), + SHELL_CMD_ARG(reset_cause, &sub_reset_cause, "Reset cause commands", + cmd_get_device_id, 1, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ );