核心功能

XWSH 的核心功能:命令解析算法、线程模型、错误处理和内部状态管理。

命令解析算法

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++;
                }
        }
        // ... 处理最后一个参数
}

算法特点

  1. 时间复杂度 O(n):仅遍历字符串一次
  2. 原地修改:将空格替换为 \0,不复制字符串
  3. 参数指针数组argv 数组存储指向原字符串各部分的指针
  4. 错误检测
    • 参数数量超过 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()):

  1. 内部命令表(xwsh_cmd_table
  2. 外部命令表(xwsh_ext_cmd_table

重名检查xwsh_set_ext_cmd_table()):

  1. 外部命令 vs 内部命令
  2. 外部命令之间互查

缓冲区管理

缓冲区 大小 用途 定义位置
输入缓冲区 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 数组存储指针,不复制字符串内容
  • 缓存友好:连续内存布局,减少缓存未命中

设计约束

硬性限制

  1. 输入长度:单行命令不超过 128 字符(XWSH_MAXINPUT
  2. 参数数量:不超过 16 个参数(XWSH_MAX_PARAM_NUM
  3. 历史记录:最多 1024 字节历史记录
  4. 命令名称:无长度限制,但需以 \0 结尾

软性约束

  1. 线程安全:外部命令表应在启动前设置,运行期间只读
  2. 上下文限制
    • xwsh_start():中断、中断底半部、线程
    • xwsh_init() / xwsh_loop():线程
  3. 标准库依赖:需要 stdio.h 用于输入输出