# varcli **Repository Path**: redocCheng/varcli ## Basic Information - **Project Name**: varcli - **Description**: 变量CLI模块,把变量按名字挂到变量表中,命令行执行 listvar / getvar / setvar 来查看与修改变量,常用于嵌入式串口调试。 - **Primary Language**: C - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-23 - **Last Updated**: 2025-12-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # varcli `varcli` 是一个轻量级“变量CLI”模块:把变量按名字挂到变量表中,通过命令行执行 `listvar / getvar / setvar` 来查看与修改变量(常用于嵌入式串口 CLI / 调试口)。 --- ## Features - 类型:`I8 / U8 / I16 / U16 / I32 / U32 / F32 / F64` - 权限:`RO / WO / RW` - 命令: - `listvar`:列出变量(name/type/perm) - `getvar `:读取变量 - `setvar `:写变量 - `setvar`: - 整数支持 `0x..`(`strto*` base=0 自动识别十进制/十六进制) - 浮点支持科学计数法(如 `1e-3`) ```shell msh >listvar name type perm g_u32 U32 RO g_u16 U16 WO g_i32 I32 RW g_f32 F32 RW msh >getvar g_f32 g_f32 = 1.250000 [RW] msh >getvar g_u32 g_u32 = 3000000000 [RO] msh >setvar g_u32 10 ERR: permission (read-only) msh >getvar g_u16 ERR: permission (write-only) ``` --- ## Files - `varcli.h`:公共 API / 类型 / 宏 - `varcli.c`:核心实现 - `varcli_cfg.h`:配置项(默认宏) - `varcli_port.c`:对 `xcmd` 的适配(`varcli_print` + 命令注册/导出) - `varcli_example.c`:示例(变量 + 注册方式) --- ## Configuration 在 `varcli_cfg.h` 中配置(可在工程编译宏中覆盖): - `VARCLI_PRINT_BUF_MAX_LENGTH`:`varcli_print()` 缓冲区长度(默认 128) - `VARCLI_VAR_MAX_NUM`:变量名最大长度(默认 32) - `VARCLI_ENABLE_EXPORT`:开启“自动导出(section 收集)”模式(本仓库 `inc/varcli_cfg.h` 默认定义) --- ## Export Mode ### 1) 动态注册 - **变量来源**:运行时调用 `varcli_register_vars()` 把 `varcli_item_t` 插入链表 - **命令注册**:调用 `varcli_init()`(内部通过 `varcli_port_init()` 适配 `xcmd_cmd_register()` 或 `XCMD_EXPORT_CMD(...)`) ```c #include "varcli.h" static volatile uint32_t g_uptime_ms; /* 注意:未开启 VARCLI_ENABLE_EXPORT 时,varcli_item_t 可能包含 next 字段,需要置 NULL */ static varcli_item_t g_vars[] = { { "uptime_ms", (void*)&g_uptime_ms, VARCLI_U32, VARCLI_PERM_R, NULL }, }; void app_varcli_init(void) { (void)varcli_init(); (void)varcli_register_vars(g_vars, sizeof(g_vars) / sizeof(g_vars[0])); } ``` ### 2) 自动导出 开启后,变量不再通过 `varcli_register_vars()` 注册,而是通过“导出宏”把变量描述项放入固定 section(`_varcli_cmd_list`),由链接器收集后运行时遍历。 #### 2.1 开启宏 在工程编译宏或 `varcli_cfg.h` 中定义: ```c #define VARCLI_ENABLE_EXPORT ``` > 建议由工程控制开关,不要在库内部强制开启,方便切换模式。 #### 2.2 Linker Script(.ld 修改) 必须在链接脚本中保留导出段并提供起止符号(名称必须与你代码一致): ```ld /* 在 SECTIONS { ... } 中加入 */ .varcli : { . = ALIGN(4); (_varcli_list_start = .); KEEP(*(_varcli_cmd_list)) (_varcli_list_end = .); . = ALIGN(4); } > FLASH ``` 常见坑: * 若开启 `--gc-sections`,没有 `KEEP()` 导出条目可能被丢掉,导致 `listvar` 看不到变量。 * `_varcli_list_start/_varcli_list_end` 必须与代码中 `extern` 的符号一致。 * `KEEP(*(_varcli_cmd_list))` 必须与 `VARCLI_SECTION("_varcli_cmd_list")` 的 section 名一致。 #### 2.3 自动导出宏用法 你当前的导出宏如下(开启 `VARCLI_ENABLE_EXPORT` 后生效): * `VARCLI_CMD_EXPORT(_sym, _type_enum, _perm_flags)` * 名字自动使用 `#_sym` * 地址自动使用 `&(_sym)` * `VARCLI_CMD_EXPORT_NAMED(_sym, _name_str, _type_enum, _perm_flags)` * 自定义 CLI 名字 * 地址自动使用 `&(_sym)` * `VARCLI_CMD_EXPORT_RAW(_sym, _name_str, _addr_ptr, _type_enum, _perm_flags)` * 显式传入地址(更底层,通常不常用) 示例: ```c #include "varcli.h" volatile uint32_t g_u32 = 1234; volatile float g_f32 = 0.5f; /* 名字 = "g_u32" */ VARCLI_CMD_EXPORT(g_u32, VARCLI_U32, VARCLI_PERM_RW); /* 名字 = "exp_rw_f32" */ VARCLI_CMD_EXPORT_NAMED(g_f32, "exp_rw_f32", VARCLI_F32, VARCLI_PERM_RW); ``` 注意事项: * `_sym` 必须是合法 C 标识符,并且同一个 `_sym` 不要在多个地方重复导出(否则 `varcli_var_##_sym` 会重定义)。 * `_name_str` 建议不超过 `VARCLI_VAR_MAX_NUM`(你的匹配逻辑会限制输入长度)。 * 导出的变量必须是全局或 `static` 全局,地址要长期有效。 --- ## Notes * 变量名输入长度:`getvar/setvar` 的 `` 建议不超过 `VARCLI_VAR_MAX_NUM`(超长会被拒绝或匹配失败,取决于你的实现)。 ---