Commit 95b4d372 authored by Krzysztof Chruściński's avatar Krzysztof Chruściński Committed by Anas Nashif
Browse files

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: default avatarKrzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
parent efeb7fa7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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.

+98 −104
Original line number Diff line number Diff line
@@ -11,6 +11,11 @@
#include <device.h>
#include <sensor.h>

#define SENSOR_GET_HELP \
	"Get sensor data. Channel names are optional. All channels are read " \
	"when no channels are provided. Syntax:\n" \
	"<device_name> <channel name 0> .. <channel name 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;
	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]));
	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 {
		for (int i = 2; i < argc; i++) {
			err = handle_channel_by_name(shell, dev, argv[i]);
			if (err < 0) {
				shell_error(shell,
					"Could not read channel idx %d=%s",
					idx, sensor_channel_name[idx]);
				return -EIO;
					"Failed to read channel (%s)", argv[i]);
			}
		}
	}

	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]));
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)
{
	int cnt = 0;

	entry->syntax = NULL;
	entry->handler = NULL;
	entry->help  = NULL;
	entry->subcmd = &dsub_channel_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++;
		}
	}

	} else {
		shell_error(shell, "Could not bind the %s sensor", argv[1]);
		return -ENXIO;
}

	return 0;
}
static void device_name_get(size_t idx, struct shell_static_entry *entry);

static int cmd_list_sensors(const struct shell *shell,
			      size_t argc, char **argv)
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;

	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);
		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++;
		}
	}

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_sensor,
	SHELL_CMD_ARG(get, NULL, "<device_name> [chanel_idx]", cmd_get_sensor,
		      2, 1),
	SHELL_CMD(list, NULL, "List configured sensors", cmd_list_sensors),
	SHELL_CMD_ARG(list_channels, NULL, "<device_name>",
		  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
	);