本帖最后由 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 转义码。
一些截图:
以下以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 的使用提供了流畅的交互体验。为用户提供了直观的调用流程,学习曲线平缓,心智负担较低。
欢迎大家体验!
|