drivers: watchdog: add WDT shell commands
Add shell commands to setup, disable, install timeout and feed a watchdog device. These commands reflect watchdog API. Signed-off-by: Benjamin Lemouzy <blemouzy@centralp.fr>
This commit is contained in:
parent
adf0b6d957
commit
d4e33c5708
4 changed files with 201 additions and 0 deletions
|
@ -44,5 +44,6 @@ zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c wdt_dw_common.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_WDT_INTEL_ADSP wdt_intel_adsp.c wdt_dw_common.c)
|
zephyr_library_sources_ifdef(CONFIG_WDT_INTEL_ADSP wdt_intel_adsp.c wdt_dw_common.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_WDT_ANDES_ATCWDT200 wdt_andes_atcwdt200.c)
|
zephyr_library_sources_ifdef(CONFIG_WDT_ANDES_ATCWDT200 wdt_andes_atcwdt200.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_WDT_NXP_FS26 wdt_nxp_fs26.c)
|
zephyr_library_sources_ifdef(CONFIG_WDT_NXP_FS26 wdt_nxp_fs26.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_WDT_SHELL wdt_shell.c)
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE wdt_handlers.c)
|
zephyr_library_sources_ifdef(CONFIG_USERSPACE wdt_handlers.c)
|
||||||
|
|
|
@ -118,4 +118,6 @@ source "drivers/watchdog/Kconfig.nxp_fs26"
|
||||||
|
|
||||||
source "drivers/watchdog/Kconfig.ambiq"
|
source "drivers/watchdog/Kconfig.ambiq"
|
||||||
|
|
||||||
|
source "drivers/watchdog/Kconfig.shell"
|
||||||
|
|
||||||
endif # WATCHDOG
|
endif # WATCHDOG
|
||||||
|
|
9
drivers/watchdog/Kconfig.shell
Normal file
9
drivers/watchdog/Kconfig.shell
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Copyright (c) 2023 Centralp
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config WDT_SHELL
|
||||||
|
bool "Watchdog (WDT) shell"
|
||||||
|
default y
|
||||||
|
depends on SHELL
|
||||||
|
help
|
||||||
|
Enable WDT shell.
|
189
drivers/watchdog/wdt_shell.c
Normal file
189
drivers/watchdog/wdt_shell.c
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Centralp
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
#include <zephyr/drivers/watchdog.h>
|
||||||
|
|
||||||
|
#define WDT_SETUP_HELP \
|
||||||
|
"Set up watchdog instance. Syntax:\n" \
|
||||||
|
"<device>"
|
||||||
|
|
||||||
|
#define WDT_DISABLE_HELP \
|
||||||
|
"Disable watchdog instance. Syntax:\n" \
|
||||||
|
"<device>"
|
||||||
|
|
||||||
|
#define WDT_TIMEOUT_HELP \
|
||||||
|
"Install a new timeout. Syntax:\n" \
|
||||||
|
"<device> <none|cpu|soc> <min_ms> <max_ms>"
|
||||||
|
|
||||||
|
#define WDT_FEED_HELP \
|
||||||
|
"Feed specified watchdog timeout. Syntax:\n" \
|
||||||
|
"<device> <channel_id>"
|
||||||
|
|
||||||
|
static const char *const wdt_reset_name[] = {
|
||||||
|
[WDT_FLAG_RESET_NONE] = "none",
|
||||||
|
[WDT_FLAG_RESET_CPU_CORE] = "cpu",
|
||||||
|
[WDT_FLAG_RESET_SOC] = "soc",
|
||||||
|
};
|
||||||
|
|
||||||
|
struct args_index {
|
||||||
|
uint8_t device;
|
||||||
|
uint8_t reset;
|
||||||
|
uint8_t timeout_min;
|
||||||
|
uint8_t timeout_max;
|
||||||
|
uint8_t channel_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct args_index args_indx = {
|
||||||
|
.device = 1,
|
||||||
|
.reset = 2,
|
||||||
|
.timeout_min = 3,
|
||||||
|
.timeout_max = 4,
|
||||||
|
.channel_id = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_named_int(const char *name, const char *const keystack[], size_t count)
|
||||||
|
{
|
||||||
|
char *endptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Attempt to parse name as a number first */
|
||||||
|
i = strtoul(name, &endptr, 0);
|
||||||
|
|
||||||
|
if (*endptr == '\0') {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Name is not a number, look it up */
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (strcmp(name, keystack[i]) == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_setup(const struct shell *sh, size_t argc, char *argv[])
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
|
||||||
|
dev = device_get_binding(argv[args_indx.device]);
|
||||||
|
if (!dev) {
|
||||||
|
shell_error(sh, "WDT device not found");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wdt_setup(dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_disable(const struct shell *sh, size_t argc, char *argv[])
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
|
||||||
|
dev = device_get_binding(argv[args_indx.device]);
|
||||||
|
if (!dev) {
|
||||||
|
shell_error(sh, "WDT device not found");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wdt_disable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_timeout(const struct shell *sh, size_t argc, char *argv[])
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int flags;
|
||||||
|
int timeout_min;
|
||||||
|
int timeout_max;
|
||||||
|
struct wdt_timeout_cfg cfg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = device_get_binding(argv[args_indx.device]);
|
||||||
|
if (!dev) {
|
||||||
|
shell_error(sh, "WDT device not found");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = parse_named_int(argv[args_indx.reset], wdt_reset_name, ARRAY_SIZE(wdt_reset_name));
|
||||||
|
if (flags < 0) {
|
||||||
|
shell_error(sh, "Reset mode '%s' unknown", argv[args_indx.reset]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_min = parse_named_int(argv[args_indx.timeout_min], NULL, 0);
|
||||||
|
if (timeout_min < 0) {
|
||||||
|
shell_error(sh, "Unable to convert '%s' to integer", argv[args_indx.timeout_min]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_max = parse_named_int(argv[args_indx.timeout_max], NULL, 0);
|
||||||
|
if (timeout_max < 0) {
|
||||||
|
shell_error(sh, "Unable to convert '%s' to integer", argv[args_indx.timeout_max]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.window.min = timeout_min;
|
||||||
|
cfg.window.max = timeout_max;
|
||||||
|
cfg.callback = NULL;
|
||||||
|
cfg.flags = flags;
|
||||||
|
|
||||||
|
rc = wdt_install_timeout(dev, &cfg);
|
||||||
|
if (rc >= 0) {
|
||||||
|
shell_print(sh, "Channel ID = %d", rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_feed(const struct shell *sh, size_t argc, char *argv[])
|
||||||
|
{
|
||||||
|
const struct device *dev;
|
||||||
|
int channel_id;
|
||||||
|
|
||||||
|
dev = device_get_binding(argv[args_indx.device]);
|
||||||
|
if (!dev) {
|
||||||
|
shell_error(sh, "WDT device not found");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_id = parse_named_int(argv[args_indx.channel_id], NULL, 0);
|
||||||
|
if (channel_id < 0) {
|
||||||
|
shell_error(sh, "Unable to convert '%s' to integer", argv[args_indx.channel_id]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wdt_feed(dev, channel_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device name autocompletion support */
|
||||||
|
static void device_name_get(size_t idx, struct shell_static_entry *entry)
|
||||||
|
{
|
||||||
|
const struct device *dev = shell_device_lookup(idx, NULL);
|
||||||
|
|
||||||
|
entry->syntax = (dev != NULL) ? dev->name : NULL;
|
||||||
|
entry->handler = NULL;
|
||||||
|
entry->help = NULL;
|
||||||
|
entry->subcmd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_wdt,
|
||||||
|
SHELL_CMD_ARG(setup, &dsub_device_name, WDT_SETUP_HELP, cmd_setup,
|
||||||
|
2, 0),
|
||||||
|
SHELL_CMD_ARG(disable, &dsub_device_name, WDT_DISABLE_HELP, cmd_disable,
|
||||||
|
2, 0),
|
||||||
|
SHELL_CMD_ARG(timeout, &dsub_device_name, WDT_TIMEOUT_HELP, cmd_timeout,
|
||||||
|
5, 0),
|
||||||
|
SHELL_CMD_ARG(feed, &dsub_device_name, WDT_FEED_HELP, cmd_feed,
|
||||||
|
3, 0),
|
||||||
|
SHELL_SUBCMD_SET_END
|
||||||
|
);
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
SHELL_CMD_REGISTER(wdt, &sub_wdt, "Watchdog commands", NULL);
|
Loading…
Add table
Add a link
Reference in a new issue