ESP32C3开发指南(基于IDF):console控制台命令行交互功能 - 教程

news/2025/11/30 18:21:28/文章来源:https://www.cnblogs.com/gccbuaa/p/19289866

一、使用以下指令,创建一个工程console,意思就是控制台交互例程

idf.py create-project console

在这里插入图片描述

二、进到console工程,使用以下指令对工程进行编译

idf.py build

在这里插入图片描述

三、在主函数文件中,写入如下代码

在这里插入图片描述

/* Basic console example (esp_console_repl API)
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>// 标准输入输出(如 printf)#include <string.h> // 字符串处理(如 strcmp)#include "esp_system.h"// ESP 系统基础功能(如复位、版本)#include "esp_log.h" // ESP 日志模块(打印调试信息)#include "esp_console.h"// ESP 控制台核心 API(命令注册、REPL 交互)#include "esp_vfs_dev.h" // ESP VFS(虚拟文件系统)设备适配(如串口、USB)#include "esp_vfs_fat.h"// ESP VFS-FAT 文件系统适配(用于存储命令历史)#include "nvs.h"// NVS(非易失性存储)基础接口#include "nvs_flash.h"// NVS Flash 初始化与操作#include "cmd_system.h"// 系统相关命令(如重启、查看版本,官方预定义命令)#include "cmd_wifi.h"// WiFi 相关命令(如连接热点、查看状态,官方预定义命令)#include "cmd_nvs.h"// NVS 相关命令(如读写 NVS 数据,官方预定义命令)/** 警告:若启用了「次级串口控制台」,会打印此提示。* 原因:次级串口控制台仅支持「输出」,不支持「输入」,而交互式控制台需要输入(如敲命令),因此次级控制台无实际用途。* 解决:若看到此警告,在 menuconfig 中禁用次级串口控制台(路径:Component config → ESP System Settings → Secondary console)。*/#if SOC_USB_SERIAL_JTAG_SUPPORTED// 判断芯片是否支持 USB Serial/JTAG(如 ESP32-C3、S3) #if !CONFIG_ESP_CONSOLE_SECONDARY_NONE// 判断是否未禁用次级控制台#warning "A secondary serial console is not useful when using the console component. Please disable it in menuconfig."#endif#endifstatic const char* TAG = "example";// 日志标签(打印日志时用于区分模块)#define PROMPT_STR CONFIG_IDF_TARGET// 控制台提示符前缀,值为芯片型号(如 "esp32c3",由 CONFIG_IDF_TARGET 自动定义)/** 控制台命令历史功能:可将历史命令存储到文件、从文件加载(避免重启后丢失历史)。* 实现方式:基于 Wear Levelling(磨损均衡)库,在 Flash 上挂载 FATFS 文件系统,用于存储历史文件。* 注:此功能需在 menuconfig 中启用(CONFIG_CONSOLE_STORE_HISTORY)。*/#if CONFIG_CONSOLE_STORE_HISTORY // 若启用了「命令历史存储」配置#define MOUNT_PATH "/data" // FATFS 文件系统挂载路径(后续访问文件需用此路径前缀)#define HISTORY_PATH MOUNT_PATH "/history.txt"// 命令历史文件路径(历史命令会写入此文件)/*** @brief 初始化文件系统(用于存储命令历史)* 功能:在 Flash 的 "storage" 分区上挂载 FATFS,开启读写权限,支持磨损均衡。*/static void initialize_filesystem(void){static wl_handle_t wl_handle;// 磨损均衡句柄(静态变量,确保生命周期与程序一致)// FATFS 挂载配置:最大支持 4 个同时打开的文件,若挂载失败则自动格式化分区const esp_vfs_fat_mount_config_t mount_config = {.max_files = 4,.format_if_mount_failed = true};// 执行挂载:参数依次为「挂载路径」「Flash 分区名」「挂载配置」「磨损均衡句柄」esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(MOUNT_PATH, "storage", &mount_config, &wl_handle);if (err != ESP_OK) {// 若挂载失败,打印错误日志(不终止程序,仅禁用历史功能)ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));return;}}#endif // CONFIG_STORE_HISTORY/*** @brief 初始化 NVS(非易失性存储)* 功能:NVS 用于存储设备配置(如 WiFi 密码、用户参数),控制台部分命令(如 cmd_nvs)依赖 NVS 工作。* 处理逻辑:若 NVS 无空闲页或版本不匹配,先擦除 NVS 再初始化。*/static void initialize_nvs(void){esp_err_t err = nvs_flash_init();// 初始化 NVS Flash// 处理两种常见错误:1. NVS 无空闲页;2. NVS 版本更新(需擦除旧数据)if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK( nvs_flash_erase() );// 擦除 NVS 所有数据err = nvs_flash_init();// 重新初始化 NVS}ESP_ERROR_CHECK(err);// 若仍有错误,终止程序(NVS 初始化失败会影响后续功能)}//打印HELLOWORLDstatic int helloworld_cmd(int argc, char **argv){ESP_LOGI(TAG,"you enter the helloworld cmd");return 0;}//LED 控制命令的处理函数(输入 "led on" 或 "led off" 时执行)static int cmd_led_control(int argc, char **argv){// 检查参数数量:必须输入 "led on" 或 "led off"(argc=2)if (argc != 2) {ESP_LOGI(TAG,"用法错误!正确用法:led on/off\n");return ESP_ERR_INVALID_ARG; // 返回错误码,控制台会提示}// 处理 "on" / "off" 命令if (strcmp(argv[1], "on") == 0) {ESP_LOGI(TAG,"LED 已点亮(GPIO15)\n");} else if (strcmp(argv[1], "off") == 0) {ESP_LOGI(TAG,"LED 已熄灭(GPIO15)\n");} else {ESP_LOGI(TAG,"参数错误!仅支持 on/off\n");return ESP_ERR_INVALID_ARG;}return ESP_OK; // 返回成功,控制台无额外提示}//注册命令void set_cmd_init(void){//打印helloworld命令const esp_console_cmd_t cmd1 = {.command = "helloworld",.help = "this command just for test helloworld",.hint = NULL,.func = helloworld_cmd,};esp_console_cmd_register(&cmd1);const esp_console_cmd_t cmd_led = {.command = "led",                // 命令名(用户输入的关键词).help = "控制 LED 开关,用法:led on/off", // 帮助信息(输入 "help led" 时显示).hint = "<on/off>",              // 命令提示(输入 "led " 按 Tab 键会显示).func = cmd_led_control          // 绑定命令的处理函数};ESP_ERROR_CHECK(esp_console_cmd_register(&cmd_led)); // 注册到控制台}void app_main(void){esp_console_repl_t *repl = NULL;// REPL 句柄(指向控制台交互实例,后续用于控制控制台生命周期)//初始化 REPL 配置:使用默认配置(可后续修改提示符、命令长度等)esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();/* 自定义控制台提示符:格式为「芯片型号>」(如 "esp32c3>")* 作用:提示用户可输入命令,可根据需求修改(如改为 "cmd>")*/repl_config.prompt = PROMPT_STR ">";// 最大命令行长度:由配置项 CONFIG_CONSOLE_MAX_COMMAND_LINE_LENGTH 定义(默认 256 字符)repl_config.max_cmdline_length = CONFIG_CONSOLE_MAX_COMMAND_LINE_LENGTH;// 3. 初始化基础依赖模块initialize_nvs();// 先初始化 NVS(控制台命令可能依赖 NVS)// 若启用命令历史存储,初始化文件系统并配置历史文件路径#if CONFIG_CONSOLE_STORE_HISTORYinitialize_filesystem();   // 挂载 FATFSrepl_config.history_save_path = HISTORY_PATH; // 指定历史命令存储文件ESP_LOGI(TAG, "Command history enabled");// 打印日志:历史功能已启用#elseESP_LOGI(TAG, "Command history disabled");#endif// 4. 注册控制台命令(用户输入的命令需先注册才能被识别)esp_console_register_help_command();// 注册 "help" 命令(查看所有支持的命令)register_system_common(); // 注册系统通用命令(如 "restart" 重启、"version" 查看版本)//register_system_sleep();#if CONFIG_ESP_WIFI_ENABLED // 若启用了 WiFi 配置,注册 WiFi 相关命令register_wifi();// 注册 WiFi 命令(如 "wifi connect" 连接热点、"wifi scan" 扫描热点#endifregister_nvs();// 注册 NVS 命令(如 "nvs get" 读取 NVS、"nvs set" 写入 NVS)//注册自己的命令set_cmd_init();// 5. 根据配置选择控制台硬件接口(UART / USB CDC / USB Serial/JTAG)// 逻辑:通过 menuconfig 配置的「控制台类型」,初始化对应硬件并创建 REPL 实例#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM)// 情况1:使用 UART 作为控制台(默认 UART 或自定义 UART)esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); // UART 默认配置(波特率 115200 等)// 创建 UART 类型的 REPL 实例:参数为「UART 配置」「REPL 配置」「REPL 句柄指针」ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl));#elif defined(CONFIG_ESP_CONSOLE_USB_CDC)// 情况2:使用 USB CDC 作为控制台(如 ESP32-S3 的 USB 虚拟串口)esp_console_dev_usb_cdc_config_t hw_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();// USB CDC 默认配置ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&hw_config, &repl_config, &repl));#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)// 情况3:使用 USB Serial/JTAG 作为控制台(如 ESP32-C3 的原生 USB 接口)esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl));#else#error Unsupported console type#endif// 6. 启动交互式控制台(REPL:Read-Eval-Print Loop,读-评-印循环)// 功能:启动后控制台会持续等待用户输入→解析命令→执行命令→打印结果,直到程序退出ESP_ERROR_CHECK(esp_console_start_repl(repl));}

四、尝试编译一下,发现如下报错

报错核心原因是 找不到 cmd_system.h 头文件—— 这个文件是 ESP-IDF 官方控制台示例中 “系统命令模块” 的头文件
在这里插入图片描述
实际上这三个函数都找不到
在这里插入图片描述

五、在main目录下创建一个文件夹,叫做idf_component.yml, 这个文件是 ESP-IDF 工程的 组件依赖配置文件(通常命名为 idf_component.yml),核心作用是 告诉 ESP-IDF 编译器:工程需要依赖 cmd_system、cmd_nvs、cmd_wifi 这 3 个自定义组件,以及去哪里找到这些组件的源代码

在这里插入图片描述

六、在idf_component.yml文件下,写入如下代码

在这里插入图片描述

dependencies:  # 固定关键字:表示“工程依赖的组件列表”
cmd_system:   # 组件名:自定义的组件标识(需和组件目录名一致)
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system  # 组件路径:告诉编译器去哪里找这个组件的源代码
cmd_nvs:      # 第二个依赖组件:NVS 命令相关代码
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_nvs
cmd_wifi:     # 第三个依赖组件:WiFi 命令相关代码
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_wifi

七、添加完后再编译一下,报如下错误,说是CONFIG_CONSOLE_MAX_COMMAND_LINE_LENGTH 这个配置宏未定义

在这里插入图片描述

八、输入以下指令,将工程配置为ESP32C3芯片

 idf.py set-target esp32c3

在这里插入图片描述

九、输入以下指令,打开配置菜单

idf.py menuconfig

在这里插入图片描述

十、在这个位置,把控制台输出配置成USB模式

在这里插入图片描述

十一、先保存退出,回到代码,创建一个这个文件,然后在这个文件里面写入如下代码。这段代码是 ESP-IDF 中用于定义 menuconfig 配置菜单的 Kconfig 语法片段,作用是在配置界面中添加自定义选项,让用户可以可视化地配置控制台相关功能

在这里插入图片描述

# 定义一个名为 "Example Configuration" 的配置菜单(在 menuconfig 中会作为一个选项卡显示)
# 所有后续配置项都会包含在这个菜单下,直到 endmenu 结束
menu "Example Configuration"
# 定义第一个配置项:是否在 Flash 中存储命令历史
# "config" 是关键字,后面跟配置项名称(CONSOLE_STORE_HISTORY)
config CONSOLE_STORE_HISTORY
bool "Store command history in flash"  # 配置项类型为 bool(布尔值,复选框),显示名称为"在 Flash 中存储命令历史"
default y                              # 默认值为 y(yes,启用),即默认勾选此选项
help                                   # 帮助说明(用户按 ? 键时显示)
Linenoise line editing library provides functions to save and load
command history. If this option is enabled, initalizes a FAT filesystem
and uses it to store command history.
# 中文含义:Linenoise 行编辑库提供了保存和加载命令历史的功能。
# 若启用此选项,会初始化 FAT 文件系统,并用于存储命令历史(重启后不丢失)。
# 定义第二个配置项:最大命令行长度
config CONSOLE_MAX_COMMAND_LINE_LENGTH
int "Maximum command line length"      # 配置项类型为 int(整数),显示名称为"最大命令行长度"
default 1024                           # 默认值为 1024(单位:字符)
help                                   # 帮助说明
This value marks the maximum length of a single command line. Once it is
reached, no more characters will be accepted by the console.
# 中文含义:此值表示单个命令行的最大长度。达到该长度后,控制台将不再接受更多字符。
# 标志 "Example Configuration" 菜单定义结束
endmenu

十二、再编译一下,编译成功

在这里插入图片描述

十三、输入以下指令,进行编译、下载、调试

在这里插入图片描述

十四、下载程序,后发现有个报错,这是因为工程启用了 命令历史存储功能(CONFIG_CONSOLE_STORE_HISTORY=y),该功能需要在 Flash 中预留一个标签为 storage 的 FAT 格式分区,用于保存命令历史文件(history.txt),但当前工程的 分区表(partition table)中没有定义这个分区,因此挂载失败,但其实这个功能可有可无,它的作用就是板子重启后也能读取上你上一次敲的命令行

在这里插入图片描述

十五、回到代码,我们在工程目录下新建一个.csv文件,这个是分区表

在这里插入图片描述

十六、在分区表中写入如下代码

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 1M,
storage,  data, fat,     ,        1M,

在这里插入图片描述

十七、我们的历史命令就存储在这个分区下,保存文件

在这里插入图片描述

十八、在终端输入以下指令,进入配置菜单

 idf.py menuconfig

在这里插入图片描述

十九、进到这个路径,选择这个选项,意思就是自定义分区表 CSV 文件,保存并退出

在这里插入图片描述

二十、输入以下指令,再编译、下载程序

idf.py flash monitor

在这里插入图片描述

二十一、发现编译没过,报错, 说工程中缺少 partitions.csv 文件

在这里插入图片描述

二十二、发现原来是文件名不一致导致的

在这里插入图片描述

二十三、将文件名改成一致

在这里插入图片描述

二十四、再编译,还是报错, 说是分区表定义的总大小超过了配置的 Flash 容量:分区表总大小需要 2.1MB,但当前配置的 Flash 容量是 2MB(2048KB),空间不足导致编译失败,但是我的ESP32C3的FLASH有4M,所以我们修改以下menuconfig

在这里插入图片描述

二十五、在这个路径下,把flash修改成4M

在这里插入图片描述

二十六、再编译下载,成功了,可以敲出命令行了

在这里插入图片描述

二十七、可以输入help看看有什么命令

在这里插入图片描述

二十八、至此,命令行就可以用了

在这里插入图片描述

二十九、但是如果使用了历史命令存储,因为要写入文件的原因,敲命令行响应会比不使用历史命令存储要慢许多,大家可以两个都感受一下,就是连续敲击空格,看看新行的出现速度,但是不影响使用,只是有点不爽,这个功能也比较鸡肋,用处不大,大家按需开启

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/982104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue+devtools下载地址

https://crxdl.com/search?q=vue+devtools 上传一个包到: https://files.cnblogs.com/files/stubborn-dude/hkddcnbhifppgmfgflgaelippbigjpjo_crxdl.com_v3_5.3.4.0.zip?t=1764497205&download=true

剑出鞘

锻造矛盾的综合无处不在 冥想似乎也无法摒弃的思绪 就让它随风飘散 文字的隐喻透露阴郁 至今已然明白 我们都面临抉择 但我确信 取舍最终归于同一 倘若非然 那便要“该出手时就出手” 倒计时还在迫近 也许是时候迈开双…

第4篇 Scrum 冲刺博客

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13474这个作业的目标 完…

渗透测试中的方法论

什么是渗透测试? 在网络安全领域,渗透测试是衡量组织防御体系有效性的关键手段。然而,一个真正专业、有价值的渗透测试,绝非简单的“黑客工具堆砌”或随机的攻击尝试。其背后是一套严谨、系统化的方法论。这套方法…

德国首个AI科学中心启动研究合作

某中心与马克斯普朗克学会合作成立科学中心,聚焦人工智能、计算机视觉和机器学习研究,包含博士奖学金项目和700万欧元初始资金,推动AI技术发展与应用创新。某中心与马克斯普朗克学会启动科学中心合作 这是某中心在美…

Google Benchmark:高性能C++代码基准测试框架

Google Benchmark是一个专业的C++微基准测试库,提供精确的性能测量、统计分析和复杂度计算,支持多线程测试和自定义计数器,帮助开发者优化代码性能。Google Benchmark:高性能C++代码基准测试框架 项目描述 Google …

医疗小程序02用户注册 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

最全、最清晰、C++的 lower_bound / upper_bound 总结

最全、最清晰的 lower_bound / upper_bound 总结,包含: ✔ 功能解释(通俗 + STL 定义) ✔ 返回值含义 ✔ 典型代码例子 ✔ 在竞赛中的常用技巧 ✔ 与 equal_range 的关系 ✔ 可视化图示🔵 1. lower_bound / uppe…

密码系统设计实验3-2

密码系统设计实验3-2密码系统设计实验3-2

Mysql基础3 - 实践

Mysql基础3 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Co…

2025-12-01-Nature 本周最新文献速递

文章标题: Specificity, length and luck drive gene rankings in association studies 中文标题: 基因排名新洞察:特异性、长度与“运气”如何影响关联研究? 关键词: 全基因组关联研究、LoF负担测试、基因优先级、性…

论程序员的管理

我在it这个行业有10年左右的经验了,但我一直是个程序员。曾经一个程序员的管理人员,我的上级给我说过,程序员的管理是比较难的。 我想他这样说,一个原因是,程序员的工作成果是用代码说话的。但在编程的过程中,可…

缓解疲劳的方式有哪些?

1,睡眠质量。一些疲惫感的原因可能来源于睡眠质量不足,比如深度睡眠很少(低于20%),或者由于打呼噜、蒙着被子睡觉、睡姿压迫呼吸,导致睡眠时血氧不充分。 2,维生素摄入不充分。维生素B1缺乏与疲惫感正相关,因而…

LUA语法细节

1. 使用 nil 作比较时应该加上双引号:> type(X) nil > type(X)==nil false > type(X)=="nil" true2. Lua 把 false 和 nil 看作是"假",其他的都为"真":if false or nil then…

DevOps设备链对比,Azure 和 TikLab哪款更好用?

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Python 日期时间操作笔记

Python 日期时间操作笔记日期时间 Python 语言中,日期时间操作类(datetime)放在 datetime 包中, 需要导入 from datetime import datetime获取本地时间 获取本地日期时间(默认), datetime.now() 获取本地的日期时间…

The country with the largest area in the world

actually its USAmerica or British because the entire Pacific belongs to the USA, along with the Atlantic.

田径赛场飞驰 球类竞技闪耀

2025-11-30 10:30:00 田径赛场飞驰 球类竞技闪耀 |@bGf.2NdMeM.cOm@||@cUe.HyZxYs.cOm@||@cUh.HyZxYs.cOm@||@zAb.JiAnGYoUwL.cOm@||@dEh.2NdMeM.cOm@||@bHr.JtRuIkAnG.cOm@||@vWx.JiAnGYoUwL.cOm@||@dEa.2NdMeM.cOm@|…

一加ACE5 安装类原生系统 crDroid 12

一加ACE5 安装类原生系统 crDroid 12ACE5 安装 crDroid 12 文档地址 官方文档 Install crDroid 12 for OnePlus 13R https://crdroid.net/giulia/12/installXDA ROM 16 OnePlus 13R / Ace 5 crDroid v12 Official h…

绿茵赛场逐梦 热血竞技铸辉煌

2025-11-30 10:00:00 绿茵赛场逐梦 热血竞技铸辉煌|@dBi.DiNoObAbY.cOm@||@dBb.DiNoObAbY.cOm@||@dBu.DiNoObAbY.cOm@||@dBh.DiNoObAbY.cOm@||@dBa.DiNoObAbY.cOm@||@bHm.Hn-XyT.cOm@||@dBl.DiNoObAbY.cOm@||@dBg.DiNo…