核心功能
XWSH 的核心功能:命令解析算法、线程模型、错误处理和内部状态管理。
Categories:
2 分钟阅读
命令解析算法
XWSH 使用 xwsh_split_cmdline() 函数(xwmd/cli/xwsh/core.c:126)将命令行字符串分割为参数数组。该算法采用 单次遍历 策略,直接在输入字符串上进行修改,避免额外的内存分配。
算法原理
xwer_t xwsh_split_cmdline(char * line, xwsz_t * argc, char * argv[], xwsz_t argvsize)
{
char * p = line;
xwsz_t count = 0;
char * start = NULL;
xwer_t rc = XWOK;
while (*p) {
if ((NULL == start) && (' ' == *p)) {
p++; // 跳过前导空格
} else {
if (NULL == start) {
start = p; // 记录参数起始位置
}
if (*p == ' ') {
if (count < argvsize) {
*p = '\0'; // 终止当前参数
argv[count] = start; // 保存参数指针
count++;
} else {
rc = -E2BIG; // 参数过多错误
break;
}
start = NULL; // 重置起始位置
}
p++;
}
}
// ... 处理最后一个参数
}
算法特点
- 时间复杂度 O(n):仅遍历字符串一次
- 原地修改:将空格替换为
\0,不复制字符串 - 参数指针数组:
argv数组存储指向原字符串各部分的指针 - 错误检测:
- 参数数量超过
argvsize时返回-E2BIG - 最大参数数:
XWSH_MAX_PARAM_NUM(16)
- 参数数量超过
参数格式限制
- 不支持引号:无法处理带空格的参数(如
"file name") - 简单分割:仅按空格分割,连续空格视为一个分隔符
- 尾部空格:自动忽略命令末尾的空格
线程模型
XWSH 提供两种线程运行模式,适应不同的应用场景。
模式对比
| 特性 | 独立线程模式 (xwsh_start()) |
嵌入式模式 (xwsh_init() + xwsh_loop()) |
|---|---|---|
| 线程资源 | 需要专用栈空间 | 使用调用者线程栈 |
| 线程管理 | XWSH 内部创建管理线程 | 用户控制循环调用 |
| 优先级 | XWSH_THD_PRIORITY(实时优先级降级) |
与调用者线程相同 |
| 适用场景 | 独立 CLI 任务 | 集成到现有任务循环 |
独立线程模式
// xwmd/cli/xwsh/mi.c:24
#define XWSH_THD_PRIORITY XWOS_SKD_PRIORITY_DROP(XWOS_SKD_PRIORITY_RT_MAX, 0)
xwer_t xwsh_start(xwstk_t * stack, xwsz_t stack_size)
{
struct xwos_thd_attr attr;
xwos_thd_attr_init(&attr);
attr.name = "xwsh.thd";
attr.stack = stack;
attr.stack_size = stack_size;
attr.priority = XWSH_THD_PRIORITY;
attr.detached = true;
attr.privileged = true;
return xwos_thd_init(&xwsh_thd, &xwsh_thdd, &attr,
xwsh_thd_mainfunc, NULL);
}
线程主函数(xwsh_thd_mainfunc):
- 显示系统 logo 和版本信息
- 初始化 CherryRL 读行库
- 循环读取并执行命令
- 支持线程冻结(
xwos_cthd_freeze())
嵌入式模式
void xwsh_init(void)
{
xwsh_show_logo(); // 显示 logo
xwsh_cherryrl_init(); // 初始化 readline
}
void xwsh_loop(char * buf)
{
char * line = xwsh_cherryrl_readline(buf);
if (line != NULL) {
xwsh_run_cmdline(line); // 执行命令
}
}
使用模式:
xwsh_init();
while (!exit_condition) {
char buf[XWSH_MAXINPUT];
xwsh_loop(buf);
// 可在此处添加其他任务逻辑
}
错误处理
XWSH 遵循 XWOS 的错误处理规范,所有 API 均返回 xwer_t 类型错误码。
常见错误码
| 错误码 | 值 | 含义 | 触发条件 |
|---|---|---|---|
XWOK |
0 | 成功 | 操作正常完成 |
-EINVAL |
-22 | 无效参数 | 参数检查失败 |
-EEXIST |
-17 | 已存在 | 命令名称冲突 |
-E2BIG |
-7 | 参数过多 | 超过 XWSH_MAX_PARAM_NUM |
错误处理模式
xwer_t example_function(type param)
{
xwer_t rc = XWOK;
if (!param) {
rc = -EINVAL;
goto err_param;
}
// 主逻辑
// ...
return XWOK;
err_param:
return rc;
}
MISRA-C 合规:
- 函数最多两个
return语句 - 使用
goto进行错误清理 - 标签命名:
err_<reason>
内部状态管理
命令表管理
// xwmd/cli/xwsh/core.c:36-37
static const struct xwsh_cmd * xwsh_ext_cmd_table = NULL;
static xwsz_t xwsh_ext_cmd_table_size = 0;
查找优先级(xwsh_find_cmd()):
- 内部命令表(
xwsh_cmd_table) - 外部命令表(
xwsh_ext_cmd_table)
重名检查(xwsh_set_ext_cmd_table()):
- 外部命令 vs 内部命令
- 外部命令之间互查
缓冲区管理
| 缓冲区 | 大小 | 用途 | 定义位置 |
|---|---|---|---|
| 输入缓冲区 | XWSH_MAXINPUT(128) |
存储单行输入 | mi.h:27 |
| 提示符缓冲区 | XWSH_RL_PROMPT_MAXSIZE(64) |
存储彩色提示符 | readline.c:32 |
| 历史记录缓冲区 | XWSH_RL_HISTORY_MAXSIZE(1024) |
命令历史记录 | readline.c:33 |
资源占用统计
- 代码大小:约 3-5 KB(取决于配置)
- 栈空间:独立模式需 1-2 KB 栈空间
- 静态内存:约 1.2 KB(缓冲区)
- 无动态内存分配:适合资源受限的嵌入式环境
性能特性
时间复杂度分析
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| 命令解析 | O(n) | n 为输入字符串长度 |
| 命令查找 | O(m) | m 为命令表大小 |
| 参数分割 | O(n) | 单次遍历 |
| 历史记录检索 | O(1) | 环形缓冲区 |
内存访问模式
- 顺序访问:命令解析时线性遍历字符串
- 指针引用:
argv数组存储指针,不复制字符串内容 - 缓存友好:连续内存布局,减少缓存未命中
设计约束
硬性限制
- 输入长度:单行命令不超过 128 字符(
XWSH_MAXINPUT) - 参数数量:不超过 16 个参数(
XWSH_MAX_PARAM_NUM) - 历史记录:最多 1024 字节历史记录
- 命令名称:无长度限制,但需以
\0结尾
软性约束
- 线程安全:外部命令表应在启动前设置,运行期间只读
- 上下文限制:
xwsh_start():中断、中断底半部、线程xwsh_init()/xwsh_loop():线程
- 标准库依赖:需要
stdio.h用于输入输出