zephyr/subsys/shell/modules/device_service.c
Gerard Marull-Paretas cc2f0e9c08 pm: use enum for device PM states
Move all PM_DEVICE_STATE_* definitions to an enum. The
PM_DEVICE_STATE_SET and PM_DEVICE_STATE_GET definitions have been kept
out of the enum since they do not represent any state. However, their
name has not been changed since they will be removed soon.

All drivers and tests have been adjusted accordingly.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2021-07-07 14:13:12 -04:00

181 lines
4.4 KiB
C

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <shell/shell.h>
#include <init.h>
#include <string.h>
#include <stdio.h>
#include <device.h>
#include <sys/arch_interface.h>
extern const struct device __device_PRE_KERNEL_1_start[];
extern const struct device __device_PRE_KERNEL_2_start[];
extern const struct device __device_POST_KERNEL_start[];
extern const struct device __device_APPLICATION_start[];
extern const struct device __device_end[];
#ifdef CONFIG_SMP
extern const struct device __device_SMP_start[];
#endif
static const struct device *levels[] = {
__device_PRE_KERNEL_1_start,
__device_PRE_KERNEL_2_start,
__device_POST_KERNEL_start,
__device_APPLICATION_start,
#ifdef CONFIG_SMP
__device_SMP_start,
#endif
/* End marker */
__device_end,
};
static const char *get_device_name(const struct device *dev,
char *buf,
size_t len)
{
const char *name = dev->name;
if ((name == NULL) || (name[0] == 0)) {
snprintf(buf, len, "[%p]", dev);
name = buf;
}
return name;
}
static bool device_get_config_level(const struct shell *shell, int level)
{
const struct device *dev;
bool devices = false;
char buf[20];
for (dev = levels[level]; dev < levels[level+1]; dev++) {
if (device_is_ready(dev)) {
devices = true;
shell_fprintf(shell, SHELL_NORMAL, "- %s\n",
get_device_name(dev, buf, sizeof(buf)));
}
}
return devices;
}
static int cmd_device_levels(const struct shell *shell,
size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
bool ret;
shell_fprintf(shell, SHELL_NORMAL, "PRE KERNEL 1:\n");
ret = device_get_config_level(shell, _SYS_INIT_LEVEL_PRE_KERNEL_1);
if (ret == false) {
shell_fprintf(shell, SHELL_NORMAL, "- None\n");
}
shell_fprintf(shell, SHELL_NORMAL, "PRE KERNEL 2:\n");
ret = device_get_config_level(shell, _SYS_INIT_LEVEL_PRE_KERNEL_2);
if (ret == false) {
shell_fprintf(shell, SHELL_NORMAL, "- None\n");
}
shell_fprintf(shell, SHELL_NORMAL, "POST_KERNEL:\n");
ret = device_get_config_level(shell, _SYS_INIT_LEVEL_POST_KERNEL);
if (ret == false) {
shell_fprintf(shell, SHELL_NORMAL, "- None\n");
}
shell_fprintf(shell, SHELL_NORMAL, "APPLICATION:\n");
ret = device_get_config_level(shell, _SYS_INIT_LEVEL_APPLICATION);
if (ret == false) {
shell_fprintf(shell, SHELL_NORMAL, "- None\n");
}
#ifdef CONFIG_SMP
shell_fprintf(shell, SHELL_NORMAL, "SMP:\n");
ret = device_get_config_level(shell, _SYS_INIT_LEVEL_SMP);
if (ret == false) {
shell_fprintf(shell, SHELL_NORMAL, "- None\n");
}
#endif /* CONFIG_SMP */
return 0;
}
struct cmd_device_list_visitor_context {
const struct shell *shell;
char *buf;
size_t buf_size;
};
static int cmd_device_list_visitor(const struct device *dev,
void *context)
{
const struct cmd_device_list_visitor_context *ctx = context;
shell_fprintf(ctx->shell, SHELL_NORMAL, " requires: %s\n",
get_device_name(dev, ctx->buf, ctx->buf_size));
return 0;
}
static int cmd_device_list(const struct shell *shell,
size_t argc, char **argv)
{
const struct device *devlist;
size_t devcnt = z_device_get_all_static(&devlist);
const struct device *devlist_end = devlist + devcnt;
const struct device *dev;
ARG_UNUSED(argc);
ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL, "devices:\n");
for (dev = devlist; dev < devlist_end; dev++) {
char buf[20];
const char *name = get_device_name(dev, buf, sizeof(buf));
const char *state = "READY";
shell_fprintf(shell, SHELL_NORMAL, "- %s", name);
if (!device_is_ready(dev)) {
state = "DISABLED";
} else {
#ifdef CONFIG_PM_DEVICE
enum pm_device_state st = PM_DEVICE_STATE_ACTIVE;
int err = pm_device_state_get(dev, &st);
if (!err) {
state = pm_device_state_str(st);
}
#endif /* CONFIG_PM_DEVICE */
}
shell_fprintf(shell, SHELL_NORMAL, " (%s)\n", state);
if (!k_is_user_context()) {
struct cmd_device_list_visitor_context ctx = {
.shell = shell,
.buf = buf,
.buf_size = sizeof(buf),
};
(void)device_required_foreach(dev, cmd_device_list_visitor, &ctx);
}
}
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(sub_device,
SHELL_CMD(levels, NULL, "List configured devices by levels", cmd_device_levels),
SHELL_CMD(list, NULL, "List configured devices", cmd_device_list),
SHELL_SUBCMD_SET_END /* Array terminated. */
);
SHELL_CMD_REGISTER(device, &sub_device, "Device commands", NULL);