From 95b4d37230b3942460eeb18f608a40f95e0c2b90 Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Fri, 3 Jan 2020 11:16:30 +0100 Subject: [PATCH] drivers: sensor: shell: Improved shell support for sensors Added autocompletion to 'sensor get' command. After this change device and channels are autocompleted. It is possible to provide multiple channels for reading. Signed-off-by: Krzysztof Chruscinski --- drivers/sensor/Kconfig | 2 + drivers/sensor/sensor_shell.c | 206 +++++++++++++++++----------------- 2 files changed, 102 insertions(+), 106 deletions(-) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 44446382a9f..db56133bccd 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -22,6 +22,8 @@ config SENSOR_INIT_PRIORITY config SENSOR_SHELL bool "Enable sensor shell" + depends on SHELL + default y help This shell provides access to basic sensor data. diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index 099591b7a22..f57db033b0d 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -11,6 +11,11 @@ #include #include +#define SENSOR_GET_HELP \ + "Get sensor data. Channel names are optional. All channels are read " \ + "when no channels are provided. Syntax:\n" \ + " .. " + extern struct device __device_init_start[]; extern struct device __device_init_end[]; @@ -49,147 +54,136 @@ const char *sensor_channel_name[SENSOR_CHAN_ALL] = { [SENSOR_CHAN_ROTATION] = "rotation", }; -static int cmd_list_sensor_channels(const struct shell *shell, - size_t argc, char *argv[]) +static int handle_channel_by_name(const struct shell *shell, struct device *dev, + const char *channel_name) { - int err; - struct device *dev; + int i; struct sensor_value value[3]; + int err; - dev = device_get_binding(argv[1]); - - if (dev != NULL) { - - err = sensor_sample_fetch(dev); - if (err) { - shell_error(shell, "sensor_sample_fetch failed err=%d", - err); - return err; + for (i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) { + if (strcmp(channel_name, sensor_channel_name[i]) == 0) { + break; } + } - for (unsigned int i = 0; i < SENSOR_CHAN_ALL; i++) { - if (!sensor_channel_get(dev, i, value)) { - shell_print(shell, "idx=%d name=%s", - i, sensor_channel_name[i]); - } - } + if (i == ARRAY_SIZE(sensor_channel_name)) { + shell_error(shell, "Channel not supported (%s)", channel_name); + return -ENOTSUP; + } + err = sensor_channel_get(dev, i, value); + if (err < 0) { + return err; + } + + if (i != SENSOR_CHAN_ACCEL_XYZ && + i != SENSOR_CHAN_GYRO_XYZ && + i != SENSOR_CHAN_MAGN_XYZ) { + shell_print(shell, + "channel idx=%d %s = %10.6f", i, + sensor_channel_name[i], + sensor_value_to_double(&value[0])); } else { - shell_error(shell, "Could not bind the %s sensor", argv[1]); - return -ENXIO; + shell_print(shell, + "channel idx=%d %s x = %10.6f y = %10.6f z = %10.6f", + i, sensor_channel_name[i], + sensor_value_to_double(&value[0]), + sensor_value_to_double(&value[1]), + sensor_value_to_double(&value[2])); } return 0; } - static int cmd_get_sensor(const struct shell *shell, size_t argc, char *argv[]) { - int err; struct device *dev; - struct sensor_value value[3]; - int idx; + int err; dev = device_get_binding(argv[1]); + if (dev == NULL) { + shell_error(shell, "Device unknown (%s)", argv[1]); + } - if (dev != NULL) { - err = sensor_sample_fetch(dev); - if (err) { - shell_error(shell, "sensor_sample_fetch failed err=%d", - err); - return err; - } + err = sensor_sample_fetch(dev); + if (err < 0) { + shell_error(shell, "Failed to read sensor"); + } - if (isdigit((unsigned char)argv[2][0])) { - idx = (u8_t)atoi(argv[2]); - if (!sensor_channel_get(dev, idx, value)) { - if (idx != SENSOR_CHAN_ACCEL_XYZ && - idx != SENSOR_CHAN_GYRO_XYZ && - idx != SENSOR_CHAN_MAGN_XYZ) { - shell_print(shell, - "channel idx=%d %s = %10.6f", idx, - sensor_channel_name[idx], - sensor_value_to_double(&value[0])); - } else { - shell_print(shell, - "channel idx=%d %s = %10.6f", idx, - sensor_channel_name[idx], - sensor_value_to_double(&value[0])); - shell_print(shell, - "channel idx=%d %s = %10.6f", idx, - sensor_channel_name[idx], - sensor_value_to_double(&value[1])); - shell_print(shell, - "channel idx=%d %s = %10.6f", idx, - sensor_channel_name[idx], - sensor_value_to_double(&value[2])); - } - } else { - shell_error(shell, - "Could not read channel idx %d=%s", - idx, sensor_channel_name[idx]); - return -EIO; - } - return 0; - } - - for (unsigned int i = 0; i < SENSOR_CHAN_ALL; i++) { - if (!sensor_channel_get(dev, i, value)) { - if (i != SENSOR_CHAN_ACCEL_XYZ && - i != SENSOR_CHAN_GYRO_XYZ && - i != SENSOR_CHAN_MAGN_XYZ) { - shell_print(shell, - "channel idx=%d %s = %10.6f", i, - sensor_channel_name[i], - sensor_value_to_double(&value[0])); - } else { - shell_print(shell, - "channel idx=%d %s = %10.6f", i, - sensor_channel_name[i], - sensor_value_to_double(&value[0])); - shell_print(shell, - "channel idx=%d %s = %10.6f", i, - sensor_channel_name[i], - sensor_value_to_double(&value[1])); - shell_print(shell, - "channel idx=%d %s = %10.6f", i, - sensor_channel_name[i], - sensor_value_to_double(&value[2])); - } + if (argc == 2) { + /* read all channels */ + for (int i = 0; i < ARRAY_SIZE(sensor_channel_name); i++) { + if (sensor_channel_name[i]) { + handle_channel_by_name(shell, dev, + sensor_channel_name[i]); } } - } else { - shell_error(shell, "Could not bind the %s sensor", argv[1]); - return -ENXIO; + for (int i = 2; i < argc; i++) { + err = handle_channel_by_name(shell, dev, argv[i]); + if (err < 0) { + shell_error(shell, + "Failed to read channel (%s)", argv[i]); + } + } } return 0; } -static int cmd_list_sensors(const struct shell *shell, - size_t argc, char **argv) +static void channel_name_get(size_t idx, struct shell_static_entry *entry); + +SHELL_DYNAMIC_CMD_CREATE(dsub_channel_name, channel_name_get); + +static void channel_name_get(size_t idx, struct shell_static_entry *entry) { - struct device *dev; + int cnt = 0; - ARG_UNUSED(argc); - ARG_UNUSED(argv); + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = &dsub_channel_name; - shell_print(shell, "devices:"); - for (dev = __device_init_start; dev != __device_init_end; dev++) { - if (dev->driver_api != NULL) { - shell_print(shell, "- %s", dev->config->name); + for (int i = 0; i < SENSOR_CHAN_ALL; i++) { + if (sensor_channel_name[i] != NULL) { + if (cnt == idx) { + entry->syntax = sensor_channel_name[i]; + break; + } + cnt++; } } +} - return 0; +static void device_name_get(size_t idx, struct shell_static_entry *entry); + +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); + +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + int device_idx = 0; + struct device *dev; + + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = &dsub_channel_name; + + for (dev = __device_init_start; dev != __device_init_end; dev++) { + if ((dev->driver_api != NULL) && + strcmp(dev->config->name, "") && (dev->config->name != NULL)) { + if (idx == device_idx) { + entry->syntax = dev->config->name; + break; + } + device_idx++; + } + } } SHELL_STATIC_SUBCMD_SET_CREATE(sub_sensor, - SHELL_CMD_ARG(get, NULL, " [chanel_idx]", cmd_get_sensor, - 2, 1), - SHELL_CMD(list, NULL, "List configured sensors", cmd_list_sensors), - SHELL_CMD_ARG(list_channels, NULL, "", - cmd_list_sensor_channels, 2, 0), + SHELL_CMD_ARG(get, &dsub_device_name, SENSOR_GET_HELP, cmd_get_sensor, + 2, 255), SHELL_SUBCMD_SET_END );