今天给大家分享谷歌开源项目 esh(Embedded‑Shell),一款基于UART的轻量级嵌入式命令行Shell,内存占用小于4KB,支持C/C++/汇编,ARM、RISC‑V多架构,非常适合裸机调试、新板子快速验证硬件。
GitHub仓库:https://github.com/google/esh
开源协议:Apache‑2.0
注意:该项目不是Google官方维护产品,属于公开归档仓库。
1. esh简介
ESH 为嵌入式设备提供了一个类似终端命令行的交互界面。你可以把单片机上的各种功能函数暴露成命令,然后通过串口终端像敲Linux命令一样去调用它们。
1.1 核心特性
1. 极低的内存占用
不到 4KB 的 footprint,意味着即便在只有几十KB Flash 和几KB RAM 的MCU上也能轻松跑起来。
2. 命令注册极其简单
使用一个宏 ADD_CMD() 就能把函数暴露成命令,和写 int main(int argc, char* argv[]) 一样简单。
3. 多语言支持
支持 C、C++ 和汇编,不管你用什么语言开发,都能无缝接入。
4. 自动源文件发现
不需要手动修改任何 Makefile,构建系统会自动识别 .c、.cpp 和 .S 源文件并编译。头文件路径也是自动传递给编译器的——这对懒人开发者来说太友好了。
5. 开箱即用的示例
项目提供了大量现成的示例,覆盖了 ARM Cortex-M3/M4/M33、Cortex-A7/A53/A72、RISC-V 32/64 等多种架构,既有 QEMU 模拟的,也有真实开发板的。
1.2 支持硬件一览
| 架构 | 处理器 | 运行载体 |
|---|---|---|
| ARMv7‑M | Cortex‑M3/M4 | QEMU、Nucleo‑F401RE、TIVA‑C实物板 |
| ARMv8‑M | Cortex‑M33(双核) | QEMU仿真mps3‑an524 |
| ARMv7‑A / ARMv8‑A | Cortex‑A7/A53/A72 32/64位 | QEMU仿真树莓派2/3、virt平台,支持多核SMP |
| RISC‑V | RV32IMAC、RV64G | HiFive1‑RevB实物板、QEMU virt仿真 |
2. 实操:QEMU快速跑通RISC‑V64示例
2.1 克隆仓库
git clone https://github.com/google/esh.git
cd esh
2.2 一键安装全部依赖
仓库内置管理脚本,直接执行setup完成环境部署:
./manage -s
# 等价于 .scripts/setup
如果手动安装依赖,复制下面命令:
sudo apt install -y binutils make binutils-riscv64-linux-gnu gcc-riscv64-linux-gnu g++-riscv64-linux-gnu qemu-system-riscv64 gdb-multiarch openocd
# gdb美化配置
wget -P ~ https://git.io/.gdbinit
pip3 install pygments
2.3 编译并启动RISC‑V64仿真示例
# 进入riscv‑64仿真demo目录
cd examples/emulation/riscv-64
# 编译
make
# 运行,启动esh交互终端
make run
运行成功后,会弹出Shell交互提示符,就可以输入内置命令,也可以运行自定义注册的命令。
2.4 GDB联合调试(双终端)
终端A,启动QEMU等待调试连接:
make debug
终端B,启动gdb客户端连接:
make gdb
一边看Shell交互输出,一边断点调试裸机代码,非常适合学习RISC‑V裸机底层开发。
3. 如何添加自己的命令?核心ADD_CMD宏
esh最核心就是ADD_CMD()宏,把普通C函数注册成Shell可调用命令。
示例代码片段:
#include "shell.h"
/*
* Shell命令函数固定原型:int xxx(int argc, char** argv)
* 可放在同一个文件,也可以拆分到多个源文件
*/
int hello(int argc, char** argv) {
for (int i = 0; i < argc; i++) {
printf(argv[i]);
printf(" ");
}
printf("nPress ctrl + a, x to exit !n");
return 0;
}
ADD_CMD(hello, "Echoes the commandlinentusage: hello <any string>", hello);
- 第一个参数:shell下输入的命令名字;第二个参数:help指令展示的帮助文本,包含用法提示;第三个参数:要绑定执行的函数名。
把这个.c文件丢到工程目录,不需要修改Makefile,esh构建系统自动扫描编译。启动shell后输入help,就能看到我们新增的hello命令,执行:
hello foo bar 123
即可打印传入的参数。
你的项目里用什么嵌入式Shell?rt‑thread finsh、lwcli还是自己手写?
欢迎评论区交流!
369
