ESP32C3挂载FAT格式SD卡创建FILE_10.LOG文件失败求助
问题:ESP32C3创建序号≥10的日志文件失败
我在ESP32C3上挂载了FAT格式SD卡,读写正常。需求是自动创建现有最大序号+1的日志文件(比如目录有FILE_0.LOG、FILE_4.LOG、FILE_5.LOG时,生成FILE_6.LOG)。
编写的代码如下:
#define MOUNT_POINT "/sdcard" #define MAX_FILENAME_LENGTH 256 char next_filename[MAX_FILENAME_LENGTH]; DIR* dir; struct dirent* entry; int max_number = 0; dir = opendir(MOUNT_POINT); while ((entry = readdir(dir)) != NULL) { int current_number; if (sscanf(entry->d_name, "FILE_%d.LOG", ¤t_number) == 1) { ESP_LOGI(TAG, "Extracted number: %d , Max number: %d", current_number, max_number); if (current_number > max_number) { max_number = current_number; } } } closedir(dir); int new_number = max_number + 1; ESP_LOGI(TAG, "%d %d", max_number, new_number); snprintf(next_filename, MAX_FILENAME_LENGTH, "%s/FILE_%d.LOG", MOUNT_POINT, new_number); FILE* file = fopen(next_filename, "w"); if (file == NULL) { ESP_LOGE(TAG, "Failed to create file: %s\n", next_filename); return; } fprintf(file, "NEW LOG %d\n", new_number); fclose(file);
代码在序号小于10时可正常工作,但创建FILE_10.LOG时失败,错误日志如下:
... I (405) CL: Extracted number: 1 , Max number: 0 I (415) CL: Extracted number: 2 , Max number: 1 I (415) CL: Extracted number: 3 , Max number: 2 I (425) CL: Extracted number: 4 , Max number: 3 I (425) CL: Extracted number: 5 , Max number: 4 I (435) CL: Extracted number: 6 , Max number: 5 I (435) CL: Extracted number: 7 , Max number: 6 I (445) CL: Extracted number: 8 , Max number: 7 I (445) CL: Extracted number: 9 , Max number: 8 I (455) CL: 9 10 E (455) CL: Failed to create file: /sdcard/FILE_10.LOG
代码基于ESP-IDF的SD卡SPI示例开发,请问失败原因是什么?
原因分析与解决方案
1. 优先排查具体错误码
fopen返回NULL时,先打印errno确定具体失败原因,在错误日志后添加代码:
#include <errno.h> // ... ESP_LOGE(TAG, "Failed to create file: %s, errno: %d\n", next_filename, errno);
常见错误码对应问题:
- EEXIST:文件已存在(可能之前创建失败残留了损坏的目录项)
- ENOSPC:SD卡空间不足
- EMFILE:同时打开的文件数超过挂载时配置的上限
- EACCES:无文件创建权限
2. 最可能的核心原因
(1)FATFS长文件名支持未启用
虽然FILE_10.LOG符合FAT的8.3短文件名规则,但ESP-IDF默认可能未开启长文件名(LFN)支持,部分场景下会导致文件名解析或创建异常。
解决:
在menuconfig中开启长文件名支持:
- 进入
Component config → FAT Filesystem Support - 勾选
Enable long filename support (LFN) - 选择长文件名存储方式(推荐
Dynamic allocation)
(2)目录遍历未过滤非文件条目
readdir会返回目录中的所有条目(包括.、..目录、隐藏的长文件名辅助条目),虽然你的sscanf不会匹配这些条目,但如果SD卡目录存在异常条目,可能干扰序号计算或文件创建。
解决:
遍历目录时仅处理普通文件:
while ((entry = readdir(dir)) != NULL) { // 跳过非普通文件条目 if (entry->d_type != DT_REG) { continue; } int current_number; if (sscanf(entry->d_name, "FILE_%d.LOG", ¤t_number) == 1) { ESP_LOGI(TAG, "Extracted number: %d , Max number: %d", current_number, max_number); if (current_number > max_number) { max_number = current_number; } } }
(3)挂载时文件数上限不足
ESP-IDF的SD卡挂载配置中,max_files参数限制了同时打开的文件数,若未修改示例默认值(通常为5),可能因系统资源限制导致创建失败。
解决:
修改挂载配置的max_files参数,设置更大的值(比如20):
esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = false, .max_files = 20, // 增大同时打开的文件数上限 .allocation_unit_size = 16 * 1024 };
(4)目录打开未做错误检查
代码中未判断opendir是否成功,若目录打开失败,后续逻辑会基于无效的dir指针执行,可能导致异常。
解决:
添加目录打开失败的判断:
dir = opendir(MOUNT_POINT); if (dir == NULL) { ESP_LOGE(TAG, "Failed to open directory: %s", MOUNT_POINT); return; }
内容的提问来源于stack exchange,提问作者Tomblarom
相关产品推荐
相关产品推荐

