news 2026/8/4 22:29:50

分享一个嵌入式开发的交互式工具:CherrySH

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分享一个嵌入式开发的交互式工具:CherrySH

CherrySH 是一个专为嵌入式应用程序而设计的微型Shell,今天我们就来一起看下。

地址:

https://github.com/cherry-embedded/CherrySH

1. CherrySH简介

项目信息

详情

项目名称

CherrySH

定位

嵌入式交互式 Shell

开发语言

C

许可证

Apache-2.0

1.1 功能

  • 支持 TAB 键补全,包括命令和路径补全

  • 支持历史记录,通过按键

  • 支持环境变量,需使用$作为前缀,例如$PATH

  • 支持设定用户名、主机名、路径

  • 支持非阻塞模式,支持裸机和 RTOS

  • 支持光标左右移动,支持HOMEEND切换光标

  • 支持组合按键,包括Ctrl + \<key\>Alt + \<key\>``F1-F12` 等

  • 支持信号处理,捕获和处理不同的信号,例如Ctrl+CSIGINT和Ctrl+ZSIGTSTP,可中断当前执行的 shell 任务

  • 支持用户登录,需要实现hash函数,默认strcmp

  • 支持环境变量添加、修改、删除、读出

  • 支持文件系统,FatFS,FileX,LittleFS,RomFS等(TODO)

  • 支持 exit 函数实现终止命令执行以及现场返回并调用设定的handler,利用setjmp实现(裸机)(TODO)

  • 支持作业控制,可以在前台或后台运行命令,并使用相关的控制命令(如fg、bg、jobs)来管理和操作作业(TODO)

  • 支持多用户命令权限(TODO)

一句话说清楚:CherrySH 就是让你在 MCU 上敲命令,还能有方向键、历史、TAB 补全这些体验,而且不用 malloc。

它怎么做到的?两招:

  1. 命令注册:编译时用宏把命令塞进链接器 section,运行时直接遍历这块内存

  2. 行编辑:单独的 readline 模块处理键盘输入,全静态 buffer

2. 核心原理

2.1 整体架构

说明:

  • CherryReadLine:负责"怎么把一行字编辑好"(方向键、删除、历史、补全)

  • CherrySH:负责"拿到一行后怎么执行"(解析参数、查命令、调函数)

  • 命令表:编译时自动收集,运行时直接遍历

2.2 关键代码

注册一个命令:
staticintmy_cmd(int argc, char **argv) { chry_shell_t *csh = (void *)argv[argc + 1]; csh_printf(csh, "====== 嵌入式大杂烩 ======\r\n"); return0; } CSH_CMD_EXPORT(my_cmd, );

这个宏展开后,会在FSymTab段里放一个结构体:

// csh.h 里的定义 typedefstruct { constchar *path; // 命令路径,如 "/bin" constchar *name; // 命令名 constchar *usage; // 简短说明 constchar *help; // 详细帮助 int (*func)(int argc, char **argv); // 函数指针 } chry_syscall_t;

链接器把所有这种结构体收集到一起,形成一个"命令表"。

运行时怎么找命令?

chry_shell_task_repl()核心逻辑:

// 读一行 char *line = chry_readline(&csh->rl, buffer, size, &linesize); // 解析成 argc/argv(原地切割,空格变 \0) argc = chry_shell_parse(line, linesize, argv, MAX_ARG); // 遍历命令表找匹配 for (call = csh->cmd_tbl_beg; call < csh->cmd_tbl_end; call++) { if (路径+名字匹配) { call->func(argc, argv); // 找到就调用 break; } }

用流程图表示:

2.3 目录结构

CherrySH/ ├── chry_shell.c/h # Shell 核心(解析、执行、用户管理) ├── csh.h # 配置 + 导出宏 ├── cherryrl/ # ReadLine 模块(行编辑、历史、补全) ├── builtin/ # 内置命令示例(help、clear 等) └── samples/ # 移植示例(HPM、STM32)

3. 移植步骤

以先楫半导体hpm5301evklite为例。

  • 命令查找采用的是 gcc 的 section 功能,因此,我们需要先修改 linkerscript 文件,增加相关 section,举例 gcc ld 文件:

.text : { ..... . = ALIGN(4); __fsymtab_start = .; KEEP(*(FSymTab)) __fsymtab_end = .; . = ALIGN(4); __vsymtab_start = .; KEEP(*(VSymTab)) __vsymtab_end = .; . = ALIGN(4); }
  • 实现字符输入输出函数,接收推荐用中断 + ringbuf的形式

#include"csh.h" staticchry_shell_t csh; staticuint16_tcsh_sput_cb(chry_readline_t *rl, constvoid *data, uint16_t size) { uint16_t i; (void)rl; for (i = 0; i < size; i++) { if (status_success != uart_send_byte(HPM_UART0, ((uint8_t *)data)[i])) { break; } } return i; } staticuint16_tcsh_sget_cb(chry_readline_t *rl, void *data, uint16_t size) { uint16_t i; (void)rl; for (i = 0; i < size; i++) { if (status_success != uart_receive_byte(HPM_UART0, (uint8_t *)data + i)) { break; } } return i; }
  • 初始化 shell,参考 samples 中实现

  • 调用chry_shell_task_execchry_shell_task_repl,参考 samples 中实现

  • 配置系统环境变量

#define __ENV_PATH "/sbin:/bin" constchar ENV_PATH[] = __ENV_PATH; CSH_RVAR_EXPORT(ENV_PATH, PATH, sizeof(__ENV_PATH)); #define __ENV_ZERO "" constchar ENV_ZERO[] = __ENV_ZERO; CSH_RVAR_EXPORT(ENV_ZERO, ZERO, sizeof(__ENV_ZERO));
  • 使用CSH_CMD_EXPORT导出命令

staticintwrite_led(int argc, char **argv) { if (argc < 2) { printf("usage: write_led <status>\r\n\r\n"); printf(" status 0 or 1\r\n\r\n"); return-1; } board_led_write(atoi(argv[1]) == 0); return0; } CSH_CMD_EXPORT(write_led, );

4. 总结

4.1 CherrySH 优缺点

优点:

  • readline 独立,行编辑体验好(方向键、Home/End、Ctrl 组合键都支持)

  • 支持多线程执行模型,长耗时命令可被 Ctrl+C 打断

  • 命令路径机制(/bin、/sbin),适合命令多的场景

  • 无堆内存,资源占用可预测

缺点:

  • 必须改链接脚本,对新手不友好

  • history buffer 必须是 2 的幂,容易踩坑

  • 文档较少,主要靠看 samples 学习

如果觉得文章有帮助,麻烦帮忙转发,谢谢!

------------END------------

单片机可以用 Python 开发吗?

单片机SPI也能实现单线半双工模式?

从汇编的角度看MCU运行机制

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 18:35:41

AI助力MC1.8.8网页版开发:自动生成游戏逻辑代码

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个Minecraft 1.8.8网页版的基础框架&#xff0c;包含以下功能&#xff1a;1. 3D方块渲染引擎 2. 玩家移动控制(WASD鼠标) 3. 基础方块放置/破坏逻辑 4. 简单物理碰撞检测。使…

作者头像 李华
网站建设 2026/8/4 6:05:11

2026年01月21日全球AI前沿动态

潮起东方风正劲&#xff0c;智涌全球势如虹。2026年初&#xff0c;AI领域迎来技术爆发与产业深耕的双重热潮&#xff1a;国内以DeepSeek Model1、GLM-4.7-Flash为代表的模型架构持续突破&#xff0c;MiniMax Agent2.0、可灵AI等产品实现商业化跑通&#xff0c;医疗AI标准与应用…

作者头像 李华
网站建设 2026/7/24 3:21:00

Cursor IDEA:5分钟构建你的下一个产品原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个快速原型工具&#xff0c;支持用户通过自然语言描述生成可交互的产品原型。工具应能自动生成前端界面、后端逻辑和数据库结构。支持多种平台&#xff0c;如Web、移动端和桌…

作者头像 李华
网站建设 2026/8/1 14:49:21

3分钟搞定WSL卸载:比传统方法快10倍的技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个极速WSL卸载工具&#xff0c;优化传统卸载流程&#xff1a;1. 并行执行多个清理任务 2. 预检测可能冲突的进程 3. 使用内存缓存加速注册表操作 4. 最小化系统重启次数 5. …

作者头像 李华
网站建设 2026/8/1 1:25:37

用AI+OpenCV实现智能图像处理:5个实用案例

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个Python项目&#xff0c;使用OpenCV和AI辅助实现实时人脸检测系统。要求&#xff1a;1. 调用摄像头实时视频流 2. 使用Haar级联或DNN模型检测人脸 3. 在检测到的人脸周围绘…

作者头像 李华
网站建设 2026/7/29 8:02:26

30分钟搭建泛洪算法原型:快马平台实战教程

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 在快马平台快速构建泛洪算法原型&#xff0c;要求&#xff1a;1. 使用Python实现基础泛洪逻辑 2. 包含简单的网络拓扑配置界面 3. 实时可视化消息传播过程 4. 支持参数调整(如TTL值…

作者头像 李华