Zephyr shell系统使用指南-添加命令

本文说明如何向shell系统添加自定义命令。

Zephyr的shell系统提供一个类Unix shell界面,用户可以自定义shell命令和处理函数,通过shell界面调用这些处理函数。本文说明如何向shell系统添加自定义命令。

步骤 链接到标题

1. 实现命令处理函数 链接到标题

shell命令处理函数的参数形式是固定的

static int cmd_handler(const struct shell *shell, size_t argc, char **argv)
  • shell – [in] shell的实例后端。

  • argc – [in] 参数的个数,命令会被计入参数个数中。

  • argv – [in] 参数字符串指针,所有参数都会以字符串的形式送到命令函数.

例如执行shell命令shell_sample 1 2 3,命令函数得到的参数如下:

argc=4
argv[0]="sample"
argv[1]="1"
argv[2]="2"
argv[3]="3"

实例:这里实现三个命令函数

static int cmd_info_board(const struct shell *sh, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	shell_print(sh, CONFIG_BOARD);

	return 0;
}

static int cmd_info_version(const struct shell *sh, size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	shell_print(sh, "Zephyr version %s", KERNEL_VERSION_STRING);

	return 0;
}


static int cmd_shell_help(const struct shell *sh, size_t argc, char **argv)
{
	shell_print(sh, "show help: %d", argc);
    if(argc == 1){
        shell_help(sh);
        return SHELL_CMD_HELP_PRINTED;
    }

	for(size_t i=0; i< argc; i++){
		shell_print(sh, "check arg %d: %s", i, argv[i]);
	}

	return 0;
}

2.注册命令 链接到标题

使用下面三个宏注册静态的shell命令,一旦注册后无法在运行时修改注册的shell命令 创建命令

SHELL_CMD(_syntax, _subcmd, _help, _handler)
  • _syntax – [in] 命令符号。

  • _subcmd – [in] 指向子命令,为空表示没有子命令。子命令可以再嵌入子命令。

  • _help – [in] 命令帮助信息。

  • _handler – [in] 命令函数,,为空表示没有命令函数。

创建子命令集

SHELL_STATIC_SUBCMD_SET_CREATE(name, ...)
  • name – [in] 子命令集名.

  •  – [in] 由多个SHELL_CMDSHELL_ARG_CMD组成的,并由SHELL_SUBCMD_SET_END结束。

注册命令

SHELL_CMD_REGISTER(syntax, subcmd, help, handler)
  • syntax – [in] 命令符号

  • subcmd – [in] 指向子命令,为空表示没有子命令。

  • help – [in] 命令帮助信息。

  • handler – [in] 命令函数,,为空表示没有命令函数。

实例:这里使用上面三个宏注册命令

/* SHELL_CMD 注册两个子命令, board和version,执行时会调用cmd_info_board和cmd_info_version函数
   SHELL_STATIC_SUBCMD_SET_CREATE 将子命令组装成子命令集subinfo
   SHELL_SUBCMD_SET_END表示子命令集的结束
 */
SHELL_STATIC_SUBCMD_SET_CREATE(subinfo,
    SHELL_CMD(board, NULL, "Show board command.", cmd_info_board),
    SHELL_CMD(version, NULL, "Show info command.", cmd_info_version),
    SHELL_SUBCMD_SET_END /* Array terminated. */
);

/* 注册一个根命令shell_sample,执行根命令shell_sample时会调用cmd_shell_help
    shell_sample的子命令集为
 */
SHELL_CMD_REGISTER(shell_sample, &subinfo, "Sample commands", cmd_shell_help);

执行命令 链接到标题

上面实例中注册了根命令 shell_sample 和其子命令集subinfo,其命令为树机构

shell_sample
    ├── board
    └── version

在shell中可以执行的命令如下: 执行shell_sample 会调用cmd_shell_help显示出帮助信息和参数个数 执行shell_sample board 会调用cmd_info_board显示出开发板的字符串 执行shell_sample version 会调用cmd_info_version显示zephyr的版本

命令参数 链接到标题

使用SHELL_CMD_REGISTERSHELL_CMD注册的命令,shell系统并不会为其检查参数个数。zephyr提供了另外两个宏注册命令,在注册时可以指定参数个数。在执行shell命令时shell系统会根据指定的参数个数进行检查,如果不匹配将不执行命令函数,并进行错误提示。 创建带参数命令

SHELL_CMD_ARG(syntax, subcmd, help, handler, mand, opt)
  • syntax – [in] 命令符号。

  • subcmd – [in] 指向子命令,为空表示没有子命令。子命令可以再嵌入子命令。

  • help – [in] Pointer to a command help string.

  • handler – [in] 命令帮助信息。

  • mand – [in] 必选参数个数,参数个数包含命令本身。

  • opt – [in] 可选参数个数。

SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, mandatory, optional)
  • syntax – [in] 命令符号

  • subcmd – [in] 指向子命令,为空表示没有子命令。

  • help – [in] 命令帮助信息。

  • handler – [in] 命令函数,,为空表示没有命令函数。

  • mandatory – [in] 必选参数个数,参数个数包含命令本身。

  • optional – [in] 可选参数个数。

注意无论由那种方式定义的shell命令,shell系统都会创建argcargv并交由注册的命令函数处理。但由SHELL_CMD_ARG定义的命令会指定必选参数数量mandatory和可选参数数量optional,实际通过shell命令输入的参数数量(包含命令本身)要满足:

mandatory <= argc <= mandatory + optional

当不满足时,shell系统会检查参数数量出来并做如下提示

shell_sample_args: wrong parameter count

mandatoryoptional均被设置为0时,Shell系统不会对参数数量进行检查。 以下实例

SHELL_CMD_ARG_REGISTER(shell_sample_args, NULL, "Sample arg commands with handle", cmd_shell_help, 3, 4);

表示shell_sample_args必须有3个参数(包含shell_sample_args),但总计不能超过7个,例如 shell_sample_args 0 非法 shell_sample_args 0 1 合法 shell_sample_args 0 1 2 3 合法 shell_sample_args 0 1 2 3 4 5 6 非法

参考 链接到标题

https://docs.zephyrproject.org/latest/services/shell/index.html