Skip to content

Awesome-Embedded-Learning-Studio/bareline

Repository files navigation

Bareline

CI Release License C++23 header-only

一个零开销、header-only 的 C++23 嵌入式 shell 库。面向裸机目标(Cortex-M 级 MCU):无堆分配、无异常、命令在编译期注册。

Bareline shell on a real STM32F103C8 (Blue Pill), over USART1

跑在 STM32F103C8 真机上的 bareline shell(USART1 @115200):help / ledon / ledoff / version / stat。固件在 example/stm32/

特性

  • 行输入:归一化 \n / \r\n / \r 三种行尾(lone-CR 感知,跨行字节正确进入下一行)
  • 空白分词:零拷贝 string_view token,UTF-8 安全
  • 编译期命令注册command<Name, Func, Help>
  • 双分派:fold-expression(小列表)或 constexpr FNV-1a 哈希(大列表)自动选择,二次 name 校验防碰撞
  • 内置命令help / version / statstat 关闭时零开销
  • 后端抽象io::backend::IOAble concept)—— 自带 read/write;附带 zeros_io(回调适配器)与 mocked_io(测试用)
  • 错误上报base::expected<T, error::Error> —— shell 自身不打印,由调用者决定

快速开始

Host PC shell demo

上图:host PC 上的 bareline shell(stdin/stdout,example/main.cpp):help / echo / add / greet / ledon / version / stat。STM32 真机版见页首。

#include <bareline/bareline.hpp>

int cmd_led(std::span<std::string_view> args) {
    // args[0] 是命令名(argc/argv 约定)
    return 0;
}

using namespace bareline::cmd;
using MyCmds = command_list<command<"led", cmd_led, "toggle the LED">>;

int main() {
    YourBackend backend;  // 任何满足 bareline::io::backend::IOAble 的类型
    bareline::shell::shell<decltype(backend), MyCmds> shell(backend);
    for (;;) shell.run_once();
}

定义命令

命令是编译期的 command<Name, Func, Help> 值,收集进 command_listFunc 需满足 CommandCallable:可按 int(std::span<std::string_view>) 调用并返回 退出码(0 = 成功)。Help 可选 —— 不提供时命令仍可用,help 只打印它的名字。

using namespace bareline::cmd;

int led(std::span<std::string_view> args) { /* ... */ return 0; }
int reboot(std::span<std::string_view>)    { /* ... */ return 0; }

using MyCmds = command_list<
    command<"led",    led,    "control the LED">,
    command<"reboot", reboot>>;          // 无 help 文本

配置

shell_config 是模板,每个旋钮都在编译期确定且有默认值:

参数 默认值 含义
Prompt "> " 提示符字符串(fixed_string NTTP)
LineBufSize 128 单行输入缓冲容量
MaxArgs 16 单行最多解析的 token 数
Strategy Auto 分派策略(FoldExpression / ConstexprHash / Auto)
EnableStat true 是否收集运行时统计(false = 零开销)
using Cfg = bareline::shell::shell_config<
    "bareline> ", 256, 32,
    bareline::cmd::DispatchStrategy::ConstexprHash, false>;  // 关闭 stat

后端

后端是任何满足 io::backend::IOAble 的类型:提供 size_t read(char*, size_t)size_t write(const char*, size_t)zeros_io 把一对 C 函数指针(加一个不透明 context)适配到该 concept —— 用它包裹你的设备:

std::size_t dev_read(char* buf, std::size_t n, void* ctx) { /* ... */ }
std::size_t dev_write(const char* buf, std::size_t n, void* ctx) { /* ... */ }

bareline::io::backend::zeros_io backend(dev_read, dev_write, &my_device);
bareline::shell::shell<decltype(backend), MyCmds> shell(backend);

mocked_io(仅 hosted 测试)喂入预设字节、捕获输出 —— stdin/stdout 变体见 example/main.cpp

内置命令

help / version / stat 是保留名,由 shell 自身处理(它们需要 backend 访问, 而普通命令回调拿不到)。不要把它们放进 command_list —— static_assert 会拒绝。

  • help —— 列出所有命令(名字 + help 文本)
  • version —— 打印库版本(来自 CMake)
  • stat —— 打印运行时统计(仅当 EnableStat 为 true)

错误处理

shell 自身不打印。run_once() 返回 base::expected<int, error::Error>: 成功时是命令退出码,失败时是 error::Error(UnknownCommand / BufferOverflow)。 空行不算错误(返回 0)。

auto r = shell.run_once();
if (!r) {
    if (r.error() == bareline::error::Error::UnknownCommand) { /* ... */ }
}

构建

cmake -B build -G Ninja -DBARELINE_BUILD_TEST=ON -DBARELINE_BUILD_EXAMPLE=ON
cmake --build build
ctest --test-dir build --output-on-failure
  • example/main.cpp —— stdin/stdout 交互式 shell(hosted)。输入命令回车执行; Ctrl-C 退出(readline 在 EOF 会阻塞 —— 管道喂入会挂起,见 io::readline 的 @note)。
  • example/size_main.cpp —— ARM flash/RAM 体积探针(freestanding)。
  • example/stm32/ —— STM32F103C8(Blue Pill)固件:bareline shell 跑在真机 USART1 上,自包含构建 + OpenOCD 烧录/调试。详见 example/stm32/README.md

工具链

  • GCC / Clang(hosted,含 Catch2 测试套件)
  • arm-none-eabi-g++ —— Cortex-M3,freestanding,-fno-exceptions -fno-rtti (见 cmake/toolchains/arm-none-eabi.cmake

体积

Flash(text)目标 < 8 KB;RAM(data + bss)极小。stat_block 为 24 字节,当 shell_config::enable_stat 为 false 时经 [[no_unique_address]] + conditional_t 完全编译消除。Cortex-M3 上完整 shell 管道约 968 字节 text。

状态

v0.1 —— 核心 shell 已完成并通过审查。详见 CHANGELOG.md

许可

MIT —— 见 LICENSE

About

Bareline is expected to be a modern CLI Interactive Framework which can be exported to anywhere, using mostly in Embedded Device and PC Desktop

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors