书接上回
先实现下面两个功能:实现文件系统功能 添加命令行界面 建议你先写计划书,然后按照计划书进行开发!
项目已经成功构建!我已经完成了所有计划的任务:
- 实现文件系统功能 :
-
创建了 fs.h 头文件,定义了统一的文件系统API
-
实现了 fs.c 源文件,基于FATFS提供了文件系统操作
-
支持文件读写、目录操作和配置文件管理
-
使用了推荐的 esp_vfs_fat_spiflash_mount_rw_wl 函数进行挂载
- 添加命令行界面 :
-
创建了 cli.h 头文件,定义了CLI的API和数据结构
-
实现了 cli.c 源文件,包含命令解析和执行逻辑
-
实现了6个基本命令:
-
help - 显示帮助信息
-
ls - 列出目录内容
-
cat - 显示文件内容
-
echo - 输出文本或写入文件
-
mkdir - 创建目录
-
rm - 删除文件
- 集成到主程序 :
-
在 main.c 中添加了文件系统和CLI的初始化代码
-
实现了命令行输入循环,支持用户交互
-
更新了 CMakeLists.txt ,添加了必要的依赖项
- 构建结果 :
-
成功生成了可烧录的二进制文件
-
bootloader.bin: 0x5210字节
-
esp32c3-freertos.bin: 0x3fbe0字节
-
应用分区可用空间:75%
项目已经可以烧录到ESP32C3开发板上运行,用户可以通过串口终端与系统交互,使用命令行界面进行文件操作和系统管理。
问题总结
但是idf.py flash
idf.py monitor之后,发现还是这样:
I (278) main_task: Started on CPU0
I (308) main_task: Calling app_main()
Hello from ESP32C3 FreeRTOS Project!
Main task started
UART initialized
Flash initialized
Initializing WiFi...
WiFi initialized
WiFi initialized
WiFi mode set to 1
Connecting to WiFi AP: TestAP
Connected to WiFi AP: TestAP
Initializing network...
Network initialization completed
System running...
LED blink task started
I (329) main_task: Returned from app_main()
System running...
System running...
System running...
System running...
System running...
System running...
System running...
这是怎么回事呢?
命令行界面经过两轮之后,还没有调出来,让AI输出版本号和编译时间,以便调试
还是无法交互,没有看到提示符。为了更好的提示,请做以下操作:将版本号和编译时间写入bin文件中,让esp32c3系统启动的时候,输出版本号和编译时间,以便确定是否用了最新的版本。
现在,继续解决进入monitor没有交互的问题
告诉它怎么烧录和monitor,这样就可以自动化调式,而不用每次都是我帮它调试了。后来发现除了退出要帮它按一下ctrl+], 其它都自动化了,效果不错(ctrl+] 也可能自动化了吧,反正我看到都会帮它停一下),prompt是:
prompt 提醒,每次build完成,可以用这条命令帮我烧录:cmd.exe /c "G:\Espressif\idf_cmd_init.bat esp-idf-10fae2432b9d28444f9976c887386775 && idf.py flash" 然后用这条命令cmd.exe /c "G:\Espressif\idf_cmd_init.bat esp-idf-10fae2432b9d28444f9976c887386775 && idf.py monitor" 登录到控制台观察输出,如果还是异常重启,用ctrl+] 组合键来退出。 现在还是这样异常重启,请解决问题
中间还请教了文心一言
ESP32程序遇到了堆栈保护错误,这是典型的任务堆栈溢出问题
1
2。
问题分析
从错误日志可以看出:
错误类型:Stack protection fault(堆栈保护错误)
发生位置:main_task任务中
堆栈边界:0x3fc90c00 - 0x3fc94bf0(16KB空间)
当前指针:0x3fc909f0,已经超出堆栈下边界10字节
错误发生在_vfprintf_r函数中,说明可能是在格式化输出时使用了较大的缓冲区或递归调用。
解决方案
立即修复方法
增加main_task的堆栈大小:
c
Copy Code
// 将原来的堆栈大小(可能是8KB或12KB)增加到16KB以上
xTaskCreate(main_task, "main_task", 20480, NULL, 1, NULL); // 20KB堆栈
配置优化
在platformio.ini中启用异常解码器
4:
ini
Copy Code
monitor_filters = esp32_exception_decoder
build_type = debug
代码优化建议
避免大型局部变量:将大型数组或缓冲区声明为静态或全局
检查格式化字符串:避免过长的printf格式字符串
减少递归深度:如果使用了递归函数,限制递归层数
启用堆栈溢出检测:在FreeRTOSConfig.h中设置:
c
Copy Code
#define configCHECK_FOR_STACK_OVERFLOW 2
调试步骤
使用idf.py monitor
3查看详细的backtrace信息
分析堆栈使用情况:在任务运行时监控堆栈使用率
定位具体问题代码:根据backtrace地址找到对应的源代码位置
**建议立即将main_task堆栈增加到20KB,这通常能快速解决此类堆栈溢出问题。如果问题仍然存在,建议启用调试配置来获取更详细的错误定位信息
4
大约经过5-6轮后,终于有了改观。现在报错是这样的:
解决了这个报错。终于出来提示符了
做的很好! 现在进入控制台,可以看到提示符,可以输入help。但是它现在不停在输出提示符,请解决问题
I (261) sleep_gpio: Enable automatic switching of GPIO sleep configuration
I (268) main_task: Started on CPU0
I (298) main_task: Calling app_main()
Hello from RtemeBSD!
Version: 1.0.0
Build Time: Dec 1 2025 10:56:01
Type 'help' for available commands.
rteme> I (301) main_task: Returned from app_main()
rteme> rteme> rteme> rteme> ls
Unknown command: ls
Type 'help' for available commands.
rteme> rteme> rteme> help
Available commands:
help - Show this help message
echo - Echo the input
version - Show version information
rteme> rteme> rteme> ec
Unknown command: ec
Type 'help' for available commands.
rteme> ho hel
Unknown command: ho hel
Type 'help' for available commands.
rteme> lo
Unknown command: lo
Type 'help' for available commands.
rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme> rteme
总结
修改成功了!从终端输出可以看到,提示符不再重复输出,系统可以正常响应命令。现在我需要总结一下我所做的修改和解决的问题。我已经成功解决了ESP32C3 FreeRTOS项目中提示符重复输出的问题,具体修改如下:
1. 修改了main.c文件 :
- 添加了 got_input 标志,用于跟踪是否已经获取到输入
- 当没有获取到输入且getchar()返回EOF时,跳出读取循环,避免多次输出提示符
- 增加了非输入状态下的延迟时间,从10ms增加到100ms,减少CPU占用
- 确保在没有输入时不会重复输出提示符
2. 解决的问题 :
- 提示符不再重复输出,每次只显示一个 rteme>
- 系统可以正常响应命令,包括help、echo和version
- 减少了CPU占用,提高了系统稳定性
3. 项目状态 :
- 项目可以成功构建、烧录和运行
- 命令行界面正常工作,只有一个提示符
- 可以正常执行命令,响应及时
让它按照文档继续工作
又碰到了重复输出提示符的问题
编译、烧录和启动都正常,但是启动后,一直重复输出提示符,请解决。
解决问题。
但是只解决了重复提示符的问题,多余的工作是一件也没有做,因此再次告诉它下一步的任务:
实现文件系统。请先写好项目需求文档,再一步步实现任务。
初步实现
I (272) sleep_gpio: Enable automatic switching of GPIO sleep configuration
I (279) main_task: Started on CPU0
I (��File system initialized successfully!
rteme> I (311) main_task: Returned from app_main()
rteme> help
Available commands:
help - Show this help
echo - Echo input
version - Show version
ls - List directory contents
pwd - Show current directory
mkdir <dir> - Create directory
rmdir <dir> - Remove directory
cat <file> - Show file contents
rm <file> - Delete file
fsinfo - Show file system information
rteme> ls
Failed to open directory!
rteme> pwd
/fs
rteme> echo "hello" >test.txt
"hello" >test.txt
rteme> ls
Failed to open directory!
rteme> cat test.txt
Failed to open file!
又调试了几轮,终于成了,可以创建文件,读取文件。
让它支持文件名大小写
它提示用menuconfig更方便
可以在 menuconfig -> Component config -> FAT Filesystem support -> Long filename support 中进行修改,选择 ``Long filename buffer in heap 或 Long filename buffer on stack 配置项。然后可以在 Component config -> FAT Filesystem support -> Max long filename length 中修改最大的文件名长度。
发现fatfs不支持文件名大小写.....那算了
看了下,fatfs默认不支持文件名大小写,就不用再修改了。你看看不能不能把busybox移植过来,扩充交互命令
它说busybox移植过来工程太大
那就退而求其次
尝试使用ESP-IDF提供的esp_console组件来扩展CLI命令
添加新的命令处理函数和注册命令来轻松扩展CLI功能,例如添加cp、mv、chmod等命令。
添加之后,一输入help就重启
根本原因
console_repl任务的默认栈大小(4096字节)不足以处理help命令。当用户键入help命令时,系统需要遍历所有注册的命令并显示帮助信息,这会占用较多的栈空间,导致栈溢出和栈保护错误。
修复方案
将console_repl任务的栈大小从默认的4096字节增加到8192字节,以提供足够的栈空间来处理help命令。
这个栈大小问题,后面要仔细去研究一下。
中盘总结
现在暂时就是这样:有文件系统,但是不支持比较复杂的文件系统。
cat ls等命令都可以用,就是help会重启。

就先到这里
调试
git add .的时候报错
git add .
fatal: not a git repository: components/bt/controller/lib_esp32/../../../../.git/modules/components/bt/controller/lib_esp32
fatal: 'git status --porcelain=2' failed in submodule tools/esp-idf
我先把components目录都放到ignore目录了