硬汉嵌入式论坛

 找回密码
 立即注册
查看: 45|回复: 0
收起左侧

[客户分享] 分享一个低开销、带参数解析器的shell

[复制链接]

5

主题

16

回帖

31

积分

新手上路

积分
31
发表于 昨天 18:56 | 显示全部楼层 |阅读模式
本帖最后由 MDLZCOOL 于 2026-2-6 19:05 编辑

我利用最近的一点空闲时间写了一个带参数解析器的shell

项目主页:MDLZCOOL/ctshell: Ctshell is a low-overhead shell designed specifically for resource-constrained embedded systems.

项目文档:ctshell — ctshell 文档

特点:

* 命令补全:支持使用 TAB 键自动补全命令。
* 命令历史记录:支持使用向上 (↑) 和向下 (↓) 箭头键浏览历史记录。
* 行编辑:支持光标移动(左/右)、退格键处理以及在行内任意位置插入文本。
* 环境变量:支持设置、取消设置、列出变量,并使用“$”前缀进行内联扩展。
* 非阻塞架构:输入和处理过程解耦,使其兼容裸机和实时操作系统环境。
* 信号处理 (SIGINT):实现 setjmp/longjmp 逻辑,可通过 Ctrl+C 中断长时间运行的命令。
* 内置参数解析器:包含一个强类型参数解析器,可轻松处理自定义命令中的标志(布尔值)、整数、字符串和子命令。
* ANSI 转义序列支持:处理用于箭头键和屏幕控制的标准 VT100/ANSI 转义码。

一些截图:

help.png

sigint.png

variables.png

demo_ina226.png


以下以INA226电源监控器驱动程序的命令开发为例,全面演示如何使用子命令和多种类型参数来实现复杂命令,这是ctshell命令在嵌入式开发中最典型的使用场景。

[C] 纯文本查看 复制代码
    #include "ctshell.h"

    int cmd_ina226(int argc, char *argv[]) {
        if (argc < 2) {
            ina226_print_usage();
            return 0;
        }

        // 初始化ctshell参数解析器
        ctshell_arg_parser_t parser;
        ctshell_args_init(&parser, argc, argv);

        // 声明预期的子命令
        ctshell_expect_verb(&parser, "start");
        ctshell_expect_verb(&parser, "stop");
        ctshell_expect_verb(&parser, "status");

        // 声明预期参数,这些参数必须是强类型化的,格式为(解析器、短选项、参数别名)
        // 参数别名用于后续的值检索
        ctshell_expect_int(&parser, "-b", "bus");
        ctshell_expect_int(&parser, "-a", "addr");
        ctshell_expect_int(&parser, "-t", "battery_idx");
        ctshell_expect_bool(&parser, "-f", "keep_running");

        // 执行参数解析,底层会自动验证参数类型和格式,无需手动处理
        ctshell_args_parse(&parser);

        // 根据子命令/参数执行业务逻辑
        // ctshell_has:检查是否传入了指定的子命令/参数
        // ctshell_get_*: 获取参数值
        if (ctshell_has(&parser, "start")) {
            int bus = ctshell_has(&parser, "bus") ? ctshell_get_int(&parser, "bus") : INA226_DEFAULT_BUS;
            int addr = ctshell_has(&parser, "addr") ? ctshell_get_int(&parser, "addr") : INA226_DEFAULT_ADDR;
            int bat_idx = ctshell_has(&parser, "battery_idx") ? ctshell_get_int(&parser, "battery_idx") : 1;
            int force = ctshell_get_bool(&parser, "keep_running");
            return ina226_start(bus, addr, bat_idx, force);
        } else if (ctshell_has(&parser, "stop")) {
            return ina226_stop();
        } else if (ctshell_has(&parser, "status")) {
            return ina226_status();
        } else {
            ina226_print_usage();
        }

        return 0;
    }
    // 使用单个宏导出命令,ctshell 会自动注册,无需手动维护命令列表
    // 宏参数:<命令名称> <命令功能> <命令描述>
    CTSHELL_EXPORT_CMD(ina226, cmd_ina226, "INA226 power monitor driver");


命令注册后,即可在ctshell终端中以任意参数顺序交互式地使用该命令。以下是上面提到的 ``ina226`` 命令的实际调用方法:

[C] 纯文本查看 复制代码
    # 启动 INA226:使用默认的 I2C 总线/地址,电池索引为 2,启用连续运行模式
    ina226 start -t 2 -f

    # 启动 INA226:指定 I2C 总线 1,设备地址为 0x40,其他参数使用默认值
    ina226 start -b 1 -a 64  # 十进制数 64 对应十六进制数 0x40,ctshell 原生支持十进制/十六进制输入。

    # 停止 INA226 数据采集
    ina226 stop

    # 查看 INA226 的当前工作状态
    ina226 status

    # 查看命令用法
    ina226


Ctshell 为嵌入式 shell 的使用提供了流畅的交互体验。为用户提供了直观的调用流程,学习曲线平缓,心智负担较低。

欢迎大家体验!


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-2-7 05:58 , Processed in 0.050415 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表