ESP32 ESP-IDF移植letter-shell源码分享!调试简直不要太方便!

📅 发布时间:2026/7/9 4:05:22 👁️ 浏览次数:
ESP32 ESP-IDF移植letter-shell源码分享!调试简直不要太方便!
ESP32 ESP-IDF移植letter-shell源码分享调试简直不要太方便一、源码分享1、效果展示2、开发环境搭建3、移植流程3.1、准备一个基础工程3.2、下载letter-shell源码3.3、工程新建packages/letter_shell文件夹将letter-shell源码拷贝到工程中3.4、新建shell_linker.lf链接文件3.5、添加测试功能3.6、配置参数介绍3.7、完整工程下载二、letter-shell介绍1、核心定位与特点2、主要组件与工作原理3、典型使用流程4、编译与依赖5、应用场景6、 优势与局限7、总结三、ESP-IDF详解1、ESP32 概述2、 ESP-IDF 详解2.1 、ESP-IDF 的核心组件与架构2.2 、ESP-IDF 开发环境与工具链2.3 、ESP-IDF 开发流程简述2.4、 示例代码结构 (最简单的 Hello World)2.5、 优势与特点2.6 、适用场景3、总结一、源码分享1、效果展示2、开发环境搭建参考我这篇博文VS Code 在线安装ESP-IDFESP32开发环境搭建详细教程3、移植流程3.1、准备一个基础工程3.2、下载letter-shell源码https://github.com/NevermindZZT/letter-shell3.3、工程新建packages/letter_shell文件夹将letter-shell源码拷贝到工程中shell_port.c和shell_port.h是自己创建的。拷贝完成以后工程结构如下图所示shell_port.h#ifndef__SHELL_PORT_H__#define__SHELL_PORT_H__#includeshell.hexternShell shell;voiduserShellInit(void);#endifshell_port.c#includeshell.h#includefreertos/FreeRTOS.h#includedriver/uart.h#defineSHELL_UARTUART_NUM_0Shell shell;charshellBuffer[512];/** * brief 用户shell写 * * param data 数据 * param len 数据长度 * * return unsigned short 写入实际长度 */signedshortuserShellWrite(char*data,unsignedshortlen){returnuart_write_bytes(SHELL_UART,(constchar*)data,len);}/** * brief 用户shell读 * * param data 数据 * param len 数据长度 * * return unsigned short 读取实际长度 */signedshortuserShellRead(char*data,unsignedshortlen){returnuart_read_bytes(SHELL_UART,(uint8_t*)data,len,portMAX_DELAY);}/** * brief 用户shell初始化 * */voiduserShellInit(void){uart_config_tuartConfig{.baud_rate115200,.data_bitsUART_DATA_8_BITS,.parityUART_PARITY_DISABLE,.stop_bitsUART_STOP_BITS_1,.flow_ctrlUART_HW_FLOWCTRL_DISABLE};uart_param_config(SHELL_UART,uartConfig);uart_driver_install(SHELL_UART,256*2,0,0,NULL,0);shell.writeuserShellWrite;shell.readuserShellRead;shellInit(shell,shellBuffer,512);xTaskCreate(shellTask,shell,2048,shell,10,NULL);}3.4、新建shell_linker.lf链接文件填入如下内容[sections:shellCommand]entries:shellCommand[scheme:shell_command]entries:shellCommand-flash_rodata[mapping:shell]archive:*entries:*(shell_command);shellCommand-flash_rodataKEEP()ALIGN(4,pre,post)SURROUND(shell_command)修改CMakeLists.txt添加LDFRAGMENTS shell_linker.lfset(src_dirs letterShell)set(include_dirs letterShell)set(requires driver esp_timer)idf_component_register(SRC_DIRS ${src_dirs}INCLUDE_DIRS ${include_dirs}REQUIRES ${requires}LDFRAGMENTSshell_linker.lf)3.5、添加测试功能intreboot(intargc,char*argv[]){esp_restart();return0;}SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),reboot,reboot,reboot system);intinfo(intargc,char*argv[]){esp_chip_info_tchip_info;uint32_tflash_size;esp_chip_info(chip_info);printf(This is %s chip with %d CPU core(s), %s%s%s%s, ,CONFIG_IDF_TARGET,chip_info.cores,(chip_info.featuresCHIP_FEATURE_WIFI_BGN)?WiFi/:,(chip_info.featuresCHIP_FEATURE_BT)?BT:,(chip_info.featuresCHIP_FEATURE_BLE)?BLE:,(chip_info.featuresCHIP_FEATURE_IEEE802154)?, 802.15.4 (Zigbee/Thread):);unsignedmajor_revchip_info.revision/100;unsignedminor_revchip_info.revision%100;printf(silicon revision v%d.%d, ,major_rev,minor_rev);if(esp_flash_get_size(NULL,flash_size)!ESP_OK){printf(Get flash size failed);}printf(%PRIu32MB %s flash\n,flash_size/(uint32_t)(1024*1024),(chip_info.featuresCHIP_FEATURE_EMB_FLASH)?embedded:external);printf(Minimum free heap size: %PRIu32 bytes,esp_get_minimum_free_heap_size());return0;}SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),info,info,show system info);3.6、配置参数介绍3.7、完整工程下载博客顶部下载二、letter-shell介绍Letter-Shell是一款轻量级的、面向嵌入式系统的命令行交互组件或称为 Shell。它的核心目标是为资源受限的嵌入式设备提供一个灵活、易集成、功能实用的命令行接口方便开发者进行调试、配置和交互控制。1、核心定位与特点轻量级设计简洁代码量小对内存和 Flash 空间要求低非常适合资源有限的单片机MCU环境。易移植采用纯 C 语言实现与硬件平台和操作系统解耦良好。它主要依赖printf和scanf或类似功能的输入输出函数只要提供适配好的输入输出函数就能轻松移植到不同的平台如裸机、RTOS 等。灵活的命令注册核心机制是通过注册函数指针来添加命令。开发者可以非常方便地将自定义的函数注册为 Shell 命令。参数解析内置了基础的参数解析功能可以将用户输入的字符串参数转换成数字整数、浮点数、字符串等类型并传递给注册的命令函数。用户友好通常提供命令帮助输入help或类似命令列出所有可用命令及简介、命令补全按Tab键、历史命令记录使用方向键 ↑↓等功能提升交互体验。异步执行可选部分实现或扩展支持命令的异步执行允许在执行耗时命令时不阻塞整个 Shell 的输入。2、主要组件与工作原理命令解析器接收用户通过串口或其他输入设备输入的字符串。按照空格分割命令名和参数。在注册的命令列表中查找匹配的命令名。命令注册表一个数据结构通常是结构体数组或链表存储了所有注册的命令信息。每条记录至少包含命令名字符串如led,read_temp。命令帮助信息字符串如control LED: on/off。命令处理函数的函数指针。命令处理函数用户自定义的函数实现命令的具体功能。其函数签名通常定义为类似int cmd_func(int argc, char *argv[])的形式。argc: 参数个数包括命令名本身。argv: 参数数组指针argv[0]是命令名字符串argv[1],argv[2]… 是用户输入的参数。函数内部解析argv中的参数执行操作如控制 GPIO、读取传感器、设置参数并通过输出函数返回结果或信息。参数解析器辅助功能提供函数将argv中的字符串参数转换为整数、浮点数等类型。例如int shell_parse_int(char *arg, int *value)。输入输出适配层Shell 核心不直接操作硬件。开发者需要实现字符输入函数如shell_getchar()和字符输出函数如shell_putchar(char ch)或直接利用printf。这些函数需要适配到具体的硬件通信接口如 UART、USB CDC、网络 Socket 等。行编辑功能可选处理退格键删除、方向键移动光标、命令历史、Tab 补全等交互细节。3、典型使用流程初始化调用shell_init()设置输入输出函数。注册命令在程序初始化阶段使用类似SHELL_CMD_REGISTER(cmd_name, cmd_func, cmd_help)的宏或函数将自定义的命令处理函数注册到 Shell。轮询处理在主循环中定期调用shell_task()或shell_process()函数。这个函数会检查输入缓冲区是否有新字符。解析输入行。查找并执行匹配的命令。调用命令处理函数。输出提示符或命令执行结果。实现命令函数编写具体的cmd_func函数利用参数解析函数处理输入执行操作使用printf或类似输出反馈信息。4、编译与依赖核心依赖标准 C 库string.h,stdio.h的部分功能或自定义实现。平台依赖开发者必须提供shell_getchar()和shell_putchar(char ch)的实现或配置 Shell 使用printf/scanf。配置选项通常通过宏定义来配置 Shell 的行为如最大命令数、历史记录条数、是否支持参数解析、是否支持异步等。5、应用场景嵌入式设备调试查询状态、设置参数、触发测试。设备配置配置网络参数、工作模式等。固件升级通过命令触发 Bootloader。远程控制通过网络或其他通信接口实现远程 Shell。教学演示展示嵌入式系统交互概念。6、 优势与局限优势轻巧、易用、灵活、占用资源少、易于集成。局限功能相对基础不如bash或BusyBox强大如不支持管道|、复杂脚本等安全性通常不是首要考虑如无用户权限管理。7、总结Letter-Shell 是嵌入式开发者的一个实用工具它为 MCU 设备提供了一个便捷的命令行交互界面。其轻量化和易移植的特性使其成为资源受限环境下实现设备调试、配置和控制的理想选择。通过简单的命令注册机制开发者可以快速扩展其功能适配各种应用需求。三、ESP-IDF详解1、ESP32 概述ESP32 是由乐鑫科技Espressif Systems推出的一款高性能、低功耗、高集成度的 Wi-Fi 蓝牙双模系统级芯片SoC。它广泛应用于物联网IoT、智能家居、工业控制等领域。其关键特性包括双核处理器通常为 Xtensa LX6某些型号为 RISC-V集成 Wi-Fi (802.11 b/g/n) 和蓝牙 (包括经典蓝牙和低功耗蓝牙 BLE)丰富的外设接口S P I SPISPI,I 2 C I2CI2C,I 2 S I2SI2S,U A R T UARTUART,A D C ADCADC,D A C DACDAC,P W M PWMPWM, 触摸传感器等充足的内存RAM 和 Flash 选项多样强大的安全特性如加密加速器超低功耗设计支持多种休眠模式2、 ESP-IDF 详解ESP-IDF(Espressif IoT Development Framework) 是乐鑫官方为 ESP32、ESP32-S 系列、ESP32-C 系列等芯片提供的开发框架和 SDK软件开发工具包。它是开发基于 ESP32 芯片应用程序的首选和官方推荐工具。2.1 、ESP-IDF 的核心组件与架构ESP-IDF 是一个分层、模块化的框架硬件抽象层 (HAL)提供对芯片硬件资源如 GPIO、UART、SPI、I2C、定时器、ADC、DAC、RTC、Wi-Fi、蓝牙等进行操作的统一接口屏蔽底层硬件细节。驱动 (Drivers)在 HAL 之上提供更易用、功能更丰富的设备驱动如 SPI Flash 驱动、SD 卡驱动、以太网驱动等。FreeRTOSESP-IDF 深度集成了开源的 FreeRTOS 实时操作系统内核。它提供了任务管理、队列、信号量、软件定时器、中断管理等机制充分利用 ESP32 的多核特性任务可以在不同核心上运行。中间件Wi-Fi 协议栈实现 Wi-Fi 的 Station客户端、SoftAP接入点、Promiscuous监听模式。蓝牙协议栈实现经典蓝牙和低功耗蓝牙 (BLE) 的各种角色如 GATT Client/Server, GAP Central/Peripheral。TCP/IP 协议栈 (lwIP)轻量级的 TCP/IP 协议栈支持 IPv4/IPv6 (部分型号)、DHCP、DNS、Socket API 等。文件系统 (FATFS/VFS)支持在 SPI Flash 或外部存储设备上使用 FAT 文件系统。加密库提供 AES、SHA、RSA 等加密算法的软件和硬件加速实现。HTTP/WebSocket/MQTT 等协议库方便构建网络应用。应用程序用户编写的业务逻辑代码运行在 FreeRTOS 的任务中通过调用下层 API 实现功能。2.2 、ESP-IDF 开发环境与工具链工具链基于 GNU GCC 编译器针对 Xtensa 或 RISC-V 架构。构建系统使用CMake早期版本使用 GNU Make。开发者编写CMakeLists.txt文件来定义项目结构、源文件、依赖组件等。配置工具menuconfig。这是一个基于文本的图形化配置工具类似于 Linux Kernel 的make menuconfig用于配置 ESP-IDF 的众多选项如选择目标芯片型号配置 Wi-Fi/BT 参数调整 FreeRTOS 设置任务栈大小、优先级等配置日志输出级别和方式配置内存布局启用/禁用特定功能和外设驱动核心工具 -idf.py这是 ESP-IDF 提供的命令行工具用于执行构建、烧录、调试、监视串口输出等几乎所有开发任务。常用命令如idf.py set-target esp32(设置目标芯片)idf.py menuconfig(启动配置工具)idf.py build(编译项目)idf.py -p PORT flash(烧录固件到设备PORT 为串口如 COM3 或 /dev/ttyUSB0)idf.py -p PORT monitor(启动串口监视器查看设备日志输出)idf.py fullclean(彻底清理构建目录)2.3 、ESP-IDF 开发流程简述环境搭建在 Windows、Linux 或 macOS 上安装 ESP-IDF 开发环境包括工具链、Python、Git 等。创建项目使用idf.py create-project或复制示例项目模板。编写代码在main目录下编写应用程序代码 (通常是main.c或app_main()函数)。配置项目运行idf.py menuconfig根据需求进行配置。编译项目运行idf.py build生成可执行固件 (.bin 文件)。烧录固件将 ESP32 开发板连接到电脑运行idf.py -p PORT flash将固件烧录到设备 Flash 中。监视输出运行idf.py -p PORT monitor查看设备运行日志进行调试。可以使用ESP_LOGx(如ESP_LOGI,ESP_LOGE) 函数打印不同级别的日志。2.4、 示例代码结构 (最简单的 Hello World)#includefreertos/FreeRTOS.h#includefreertos/task.h#includeesp_log.hstaticconstchar*TAGMAIN;voidapp_main(void){while(1){ESP_LOGI(TAG,Hello World!);// 打印 Info 级别日志vTaskDelay(pdMS_TO_TICKS(1000));// 延时 1000 毫秒 (FreeRTOS 延时)}}2.5、 优势与特点官方支持由芯片原厂维护更新及时与新芯片特性同步快。功能全面提供对 ESP32 所有硬件特性和外设的底层访问。性能优化针对 ESP32 硬件进行了深度优化如 Wi-Fi/BT 共存。稳定性高经过大量商业产品验证。社区活跃用户多社区支持好问题容易找到解决方案。文档完善官方提供详尽的 API 参考指南、编程指南和示例代码。模块化易于扩展和复用代码方便管理大型项目。开源免费基于 Apache 2.0 许可证。2.6 、适用场景ESP-IDF 适用于需要深度控制硬件、追求高性能、高稳定性或需要使用 ESP32 特有功能如超低功耗协处理器 ULP的应用开发。对于快速原型开发也可以考虑基于 ESP-IDF 构建的更高级框架如 Arduino for ESP32、MicroPython但这些框架最终都依赖于 ESP-IDF 的底层功能。3、总结ESP-IDF 是开发 ESP32 系列芯片的强大、灵活且功能完备的官方框架。它提供了从硬件操作到网络协议栈的全套解决方案结合 FreeRTOS 实现了高效的多任务处理。虽然其学习曲线相对陡峭尤其是对于不熟悉嵌入式开发和 RTOS 的开发者但它提供了最直接、最强大的方式来充分利用 ESP32 的潜力是开发复杂或高性能 ESP32 应用的基石。掌握idf.py工具链和menuconfig配置是使用 ESP-IDF 的关键。