drivers: can: shell: add command for configuring a CAN controller
Add shell command for configuring the mode and bitrate of a CAN controller. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
5d6770aeea
commit
42af963db2
1 changed files with 110 additions and 5 deletions
|
@ -12,8 +12,42 @@
|
|||
|
||||
static struct zcan_work work;
|
||||
|
||||
static inline int read_options(const struct shell *shell, int pos, char **argv,
|
||||
bool *rtr, bool *ext)
|
||||
static inline int read_config_options(const struct shell *shell, int pos,
|
||||
char **argv, bool *silent, bool *loopback)
|
||||
{
|
||||
char *arg = argv[pos];
|
||||
|
||||
if (arg[0] != '-') {
|
||||
return pos;
|
||||
}
|
||||
|
||||
for (arg = &arg[1]; *arg; arg++) {
|
||||
switch (*arg) {
|
||||
case 's':
|
||||
if (silent == NULL) {
|
||||
shell_error(shell, "unknown option %c", *arg);
|
||||
} else {
|
||||
*silent = true;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (loopback == NULL) {
|
||||
shell_error(shell, "unknown option %c", *arg);
|
||||
} else {
|
||||
*loopback = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
shell_error(shell, "unknown option %c", *arg);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return ++pos;
|
||||
}
|
||||
|
||||
static inline int read_frame_options(const struct shell *shell, int pos,
|
||||
char **argv, bool *rtr, bool *ext)
|
||||
{
|
||||
char *arg = argv[pos];
|
||||
|
||||
|
@ -46,6 +80,23 @@ static inline int read_options(const struct shell *shell, int pos, char **argv,
|
|||
return ++pos;
|
||||
}
|
||||
|
||||
static inline int read_bitrate(const struct shell *shell, int pos, char **argv,
|
||||
u32_t *bitrate)
|
||||
{
|
||||
char *end_ptr;
|
||||
long val;
|
||||
|
||||
val = strtol(argv[pos], &end_ptr, 0);
|
||||
if (*end_ptr != '\0') {
|
||||
shell_error(shell, "bitrate is not a number");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*bitrate = (u32_t)val;
|
||||
|
||||
return ++pos;
|
||||
}
|
||||
|
||||
static inline int read_id(const struct shell *shell, int pos, char **argv,
|
||||
bool ext, u32_t *id)
|
||||
{
|
||||
|
@ -156,6 +207,54 @@ static void print_frame(struct zcan_frame *frame, void *arg)
|
|||
shell_fprintf(shell, SHELL_NORMAL, "|\n");
|
||||
}
|
||||
|
||||
static int cmd_config(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *can_dev;
|
||||
int pos = 1;
|
||||
bool silent = false, loopback = false;
|
||||
enum can_mode mode;
|
||||
u32_t bitrate;
|
||||
int ret;
|
||||
|
||||
can_dev = device_get_binding(argv[pos]);
|
||||
if (!can_dev) {
|
||||
shell_error(shell, "Can't get binding to device \"%s\"",
|
||||
argv[pos]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pos++;
|
||||
|
||||
pos = read_config_options(shell, pos, argv, &silent, &loopback);
|
||||
if (pos < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (silent && loopback) {
|
||||
mode = CAN_SILENT_LOOPBACK_MODE;
|
||||
} else if (silent) {
|
||||
mode = CAN_SILENT_MODE;
|
||||
} else if (loopback) {
|
||||
mode = CAN_LOOPBACK_MODE;
|
||||
} else {
|
||||
mode = CAN_NORMAL_MODE;
|
||||
}
|
||||
|
||||
pos = read_bitrate(shell, pos, argv, &bitrate);
|
||||
if (pos < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = can_configure(can_dev, mode, bitrate);
|
||||
if (ret) {
|
||||
shell_error(shell, "Failed to configure CAN controller [%d]",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_send(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *can_dev;
|
||||
|
@ -174,7 +273,7 @@ static int cmd_send(const struct shell *shell, size_t argc, char **argv)
|
|||
|
||||
pos++;
|
||||
|
||||
pos = read_options(shell, pos, argv, &rtr, &ext);
|
||||
pos = read_frame_options(shell, pos, argv, &rtr, &ext);
|
||||
if (pos < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -225,7 +324,7 @@ static int cmd_attach(const struct shell *shell, size_t argc, char **argv)
|
|||
|
||||
pos++;
|
||||
|
||||
pos = read_options(shell, pos, argv, &rtr, &ext);
|
||||
pos = read_frame_options(shell, pos, argv, &rtr, &ext);
|
||||
if (pos < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -251,7 +350,7 @@ static int cmd_attach(const struct shell *shell, size_t argc, char **argv)
|
|||
}
|
||||
|
||||
if (pos != argc) {
|
||||
pos = read_options(shell, pos, argv, &rtr_mask, NULL);
|
||||
pos = read_frame_options(shell, pos, argv, &rtr_mask, NULL);
|
||||
if (pos < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -314,6 +413,12 @@ static int cmd_detach(const struct shell *shell, size_t argc, char **argv)
|
|||
}
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(sub_can,
|
||||
SHELL_CMD_ARG(config, NULL,
|
||||
"Configure CAN controller.\n"
|
||||
" Usage: config device_name [-sl] bitrate\n"
|
||||
" -s Silent mode\n"
|
||||
" -l Listen-only mode",
|
||||
cmd_config, 3, 1),
|
||||
SHELL_CMD_ARG(send, NULL,
|
||||
"Send a CAN frame.\n"
|
||||
" Usage: send device_name [-re] id [byte_1 byte_2 ...]\n"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue