Zephyr OS 入门与实战

第12章:Shell 交互

Shell 交互

Zephyr RTOS 提供了一个功能强大的 Shell 子系统,允许开发者与设备进行交互式通信。本章将介绍如何扩展内置 Shell 命令以及开发自定义 Shell 模块。

1. 内置 Shell 命令扩展

Zephyr 提供了许多内置 Shell 命令,可以通过简单的配置来启用或扩展这些命令。

1.1 启用内置 Shell 命令

在 prj.conf 文件中启用 Shell 子系统:

CONFIG_SHELL=y
CONFIG_KERNEL_SHELL=y
        

1.2 常用内置命令

提示: 可以通过 help 命令查看当前设备支持的所有命令。

1.3 扩展内置命令功能

可以通过修改 Kconfig 选项来扩展内置命令的功能,例如启用更详细的日志输出:

CONFIG_SHELL_HISTORY=y
CONFIG_SHELL_STACK_SIZE=2048
CONFIG_SHELL_CMD_BUFF_SIZE=256
        

2. 自定义 Shell 模块开发

除了使用内置命令,Zephyr 允许开发者创建自己的 Shell 命令模块。

2.1 创建自定义命令

以下是一个简单的自定义命令示例:

#include <zephyr.h>
#include <shell/shell.h>

static int cmd_hello(const struct shell *shell, size_t argc, char **argv)
{
    shell_print(shell, "Hello, Zephyr!");
    return 0;
}

SHELL_CMD_ARG_REGISTER(hello, NULL, "Print hello message", cmd_hello, 1, 0);
        

2.2 带参数的 Shell 命令

创建带参数的 Shell 命令:

static int cmd_echo(const struct shell *shell, size_t argc, char **argv)
{
    if (argc > 1) {
        shell_print(shell, "%s", argv[1]);
    } else {
        shell_error(shell, "Usage: echo <message>");
        return -EINVAL;
    }
    return 0;
}

SHELL_CMD_ARG_REGISTER(echo, NULL, "Echo the input message", cmd_echo, 2, 0);
        

2.3 创建 Shell 模块

对于更复杂的命令集,可以创建一个完整的 Shell 模块:

#include <zephyr.h>
#include <shell/shell.h>

static int cmd_custom_ping(const struct shell *shell, size_t argc, char **argv)
{
    shell_print(shell, "pong");
    return 0;
}

static int cmd_custom_info(const struct shell *shell, size_t argc, char **argv)
{
    shell_print(shell, "Custom module v1.0");
    return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_custom,
    SHELL_CMD(ping, NULL, "Ping command", cmd_custom_ping),
    SHELL_CMD(info, NULL, "Show module info", cmd_custom_info),
    SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(custom, ⊂_custom, "Custom commands", NULL);
        

注意: 确保在 prj.conf 中启用了 Shell 子系统和你的模块:

CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y
            

2.4 动态 Shell 命令

Zephyr 还支持动态添加和移除 Shell 命令:

static const struct shell_cmd_entry dynamic_cmd = {
    .is_dynamic = true,
    .command = "dynamic",
    .help = "Dynamic command example",
    .handler = dynamic_command_handler,
    .subcmd = NULL,
};

void register_dynamic_command(void)
{
    shell_cmd_register(&dynamic_cmd);
}

void unregister_dynamic_command(void)
{
    shell_cmd_unregister(&dynamic_cmd);
}
        

扫描二维码访问课程店铺

客服小姐姐(优先添加)

扫描二维码联系客服

客服微信