# FuncShell **Repository Path**: MagicBude/funcshell ## Basic Information - **Project Name**: FuncShell - **Description**: FuncShell - 轻量级嵌入式函数调用工具 通过串口直接调用C函数,无需宏导出,支持参数自动识别和返回值显示。 专为STM32等MCU设计的交互式调试利器。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-08 - **Last Updated**: 2026-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FuncShell

轻量级嵌入式函数调用工具 - 让MCU调试更简单

License Platform Language Version

特性快速开始文档示例许可证

中文 | English

--- ## 简介 FuncShell 是一个专为嵌入式系统设计的轻量级函数调用工具。 通过串口终端,你可以**直接调用C函数**,无需编写复杂的宏导出代码。 就像在MCU上运行一个交互式的C语言REPL(Read-Eval-Print Loop)! ### 为什么选择 FuncShell? - 🚀 **零配置调用** - 无需SHELL_EXPORT_CMD宏,直接调用函数 - 🎯 **参数自动识别** - 支持数字、字符串、16进制,自动类型转换 - ⏱️ **执行时间统计** - 自动显示函数执行耗时 - 🔍 **内存读写** - 内置read_addr/write_addr,调试利器 - 💡 **轻量级设计** - 核心代码<2000行,资源占用少 - 📦 **易于移植** - 清晰的移植层接口,30分钟移植到新平台 ### 快速预览 ```bash # 串口终端输入 >>> show_system_info() <<< # 输出 ======================================== System Information ======================================== MCU: STM32G0B1RET6 Core: ARM Cortex-M0+ SYSCLK: 64000000 Hz HCLK: 64000000 Hz PCLK: 64000000 Hz Tick: 15900 ms ======================================== ; # 带参数调用 >>> test_add(100, 200) <<< ; Return: 300 # 控制LED >>> led_toggle() <<< ; # 查看系统tick >>> HAL_GetTick() <<< ; Return: 15900 ``` ### 与其他方案对比 | 特性 | FuncShell | Letter-Shell | microshell | USMART | |------|-----------|--------------|------------|--------| | 直接调用C函数 | ✅ | ⚠️需宏导出 | ❌ | ✅ | | 参数自动识别 | ✅ | ⚠️部分支持 | ❌ | ✅ | | 返回值显示 | ✅ | ⚠️需手动 | ❌ | ✅ | | 执行时间统计 | ✅ | ❌ | ❌ | ✅ | | 代码量 | 中等 | 大 | 小 | 中等 | | 开源协议 | MIT | MIT | MIT | 商业 | | 文档质量 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | | 中文支持 | ✅ | ✅ | ❌ | ✅ | | 移植难度 | 简单 | 中等 | 简单 | 简单 | --- ## 特性 ### 核心功能 #### 1. 直接调用C函数 无需使用 `SHELL_EXPORT_CMD` 或其他宏,只需在函数表中注册即可: ```c const funcshell_cmd_t cmd_table[] = { {"cmd_test_dac", (void*)cmd_test_dac, "DAC test"}, {"cmd_get_tick", (void*)cmd_get_tick, "Get system tick"}, {"read_addr", (void*)read_addr, "Read memory"}, }; ``` #### 2. 智能参数识别 自动识别并转换参数类型: ```bash # 十进制数字 test_add(100, 200) # 十六进制数字 read_addr(0x08000000) # 字符串 test_print("Hello World") # 无参数函数 led_toggle() ``` #### 3. 返回值自动显示 函数返回值自动打印,无需手动添加printf: ```bash # 输入 read_addr(0x08000000) # 输出 read_addr(0x08000000); Return: 0x20002000 ``` #### 4. 执行时间统计 使用 `runtime 1` 开启后,自动显示每个函数的执行时间: ```bash # 输入 runtime 1 cmd_delay_ms(1000) # 输出 cmd_delay_ms(1000); Return: 0 Function Run Time: 1000.2ms ``` #### 5. 内存读写 内置调试工具,方便查看和修改寄存器: ```bash # 读取Flash起始地址 read_addr(0x08000000) # 写入SRAM write_addr(0x20000000, 0x12345678) ``` ### 系统命令 ```bash ? # 显示帮助信息 help # 显示帮助信息 list # 列出所有可用函数 id # 显示函数ID列表 hex # 参数以16进制显示 dec # 参数以10进制显示 runtime # 开启/关闭执行时间统计 ``` --- ## 快速开始 ### 1. 克隆仓库 ```bash git clone https://github.com/MagicBude/funcshell.git # 或使用Gitee镜像 git clone https://gitee.com/MagicBude/funcshell.git ``` ### 2. 项目集成 将以下文件添加到你的项目: ``` funcshell/ ├── src/ │ ├── funcshell.c # 核心功能 │ ├── funcshell.h │ ├── fs_parser.c # 命令解析 │ ├── fs_parser.h │ ├── fs_string.c # 字符串处理 │ ├── fs_string.h │ └── fs_config.h # 配置文件 └── port/ ├── fs_port.c # 移植层(需要实现) └── fs_port.h ``` ### 3. 移植接口实现 在 `fs_port.c` 中实现以下接口: ```c /** * @brief 获取串口输入字符串 * @retval 命令字符串指针,NULL表示无数据 */ char* fs_get_input_string(void) { // 实现串口数据接收 // 返回完整的命令行字符串 } /** * @brief 串口输出函数 * @param[in] fmt 格式化字符串 * @retval 输出字符数 */ int fs_printf(const char* fmt, ...) { // 实现串口输出,类似printf } /** * @brief 获取系统时钟(可选) * @retval 系统滴答计数(ms) */ uint32_t fs_get_tick(void) { return HAL_GetTick(); // STM32 HAL示例 } ``` ### 4. 初始化FuncShell ```c #include "funcshell.h" int main(void) { // 系统初始化 HAL_Init(); SystemClock_Config(); // 串口初始化(根据你的硬件配置) MX_USART_Init(); // 初始化FuncShell(传入系统时钟频率,单位MHz) funcshell_init(64); // 64MHz while (1) { // 如果未使用定时器扫描,需要周期性调用 #if FS_ENTIMX_SCAN == 0 funcshell_scan(); #endif } } ``` ### 5. 注册函数 在 `funcshell_config.c` 中注册你的函数: ```c #include "funcshell.h" #include "your_project.h" // 定义函数表 const funcshell_cmd_t funcshell_cmd_table[] = { // 格式:{"函数原型", 函数指针, "描述"} {"uint32_t HAL_GetTick(void)", (void*)HAL_GetTick, "Get system tick"}, // 添加你的自定义函数 {"void led_on(void)", (void*)led_on, "Turn on LED"}, {"void led_off(void)", (void*)led_off, "Turn off LED"}, {"uint32_t test_add(uint32_t a, uint32_t b)", (void*)test_add, "Add two numbers"}, }; // 计算函数数量 const uint8_t funcshell_cmd_count = sizeof(funcshell_cmd_table) / sizeof(funcshell_cmd_table[0]); ``` ### 6. 开始使用 打开串口终端(115200, 8N1),输入命令: ```bash # 查看帮助 help # 列出所有函数 list # 调用函数 HAL_GetTick() led_toggle() test_add(100, 200) # 开启时间统计 runtime 1 ``` --- ## 配置选项 在 `fs_config.h` 中可以配置: ```c /* 缓冲区大小 */ #define FS_MAX_CMD_LEN 200 /* 命令最大长度 */ #define FS_MAX_PARAM_NUM 10 /* 最大参数数量 */ #define FS_PARM_LEN 200 /* 参数缓冲区大小 */ /* 功能开关 */ #define FS_USE_HELP 1 /* 1=启用帮助,0=禁用 */ #define FS_USE_WRFUNS 1 /* 1=启用内存读写,0=禁用 */ #define FS_ENTIMX_SCAN 1 /* 1=定时器扫描,0=手动扫描 */ /* 定时器配置(如果启用FS_ENTIMX_SCAN) */ #define FS_TIMX TIM6 #define FS_TIMX_PRESCALER 63 /* 64MHz/(63+1) = 1MHz */ #define FS_TIMX_PERIOD 999 /* 1ms中断周期 */ ``` --- ## 文档 - [快速入门](docs/GETTING_STARTED.md) - 10分钟快速上手指南 - [API文档](docs/API.md) - 完整的API参考 - [移植指南](docs/PORTING.md) - 如何移植到新平台 - [架构设计](docs/ARCHITECTURE.md) - 技术架构和核心算法 - [常见问题](docs/FAQ.md) - 常见问题解答 --- ## 示例工程 - [STM32F103](examples/stm32f103/) - STM32F103RCT6示例 - [STM32G0B1](examples/stm32g0b1/) - STM32G0B1RET6示例 - [STM32F407](examples/stm32f407/) - STM32F407VET6示例 --- ## 支持的平台 - ✅ STM32F1/F4/F7/G0/H7系列 - ✅ 其他Cortex-M系列MCU - 🔄 ESP32(计划中) - 🔄 RISC-V(计划中) --- ## 贡献 欢迎贡献!请阅读 [CONTRIBUTING.md](CONTRIBUTING.md) --- ## 许可证 本项目采用 [MIT License](LICENSE) 开源协议。 --- ## 致谢 本项目受 [USMART](https://www.openedv.com/) 启发,感谢正点原子提供的优秀设计思路。同时感谢开源社区的支持与贡献。 --- ## 联系方式 - GitHub: [@MagicBude](https://github.com/MagicBude) - Gitee: [@MagicBude](https://gitee.com/MagicBude) --- 如果这个项目对你有帮助,请给个⭐**Star**⭐支持一下! --- **项目状态**: 🚧 开发中 | **版本**: v1.0.0 | **日期**: 2026-07-08