简介
本章涉及知识点:ESP32 SPIFFS文件系统、日志输出。
ESP-IDF版本:V5.1.2
源码
小智学长的源码:DesktopScreen 7 文件系统
系统配置
如果是自己构建的项目,如图。要在CMakeLists中配置上spiffs。
如果是直接跑官方例程则忽略系统配置部分。
复制分区表到项目的文件夹目录下,如图所示。复制官方例程中的项目分区表即可。
在TERMINAL中断输入idf.py menuconfig进行下图的配置
一切都配置完成后按Q退出就好了
程序实现
声明结构体conf
static const char *TAG = "spiffs";
esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs", //文件系统的文件路径前缀
.partition_label = NULL,
.max_files = 5, //同时可以最大打开的文件数
.format_if_mount_failed = true // 挂载失败则格式化文件系统
};
SPIFFS文件系统初始化
void Spiffs_init(void)
{
ESP_LOGI(TAG, "Initializing SPIFFS");
// Use settings defined above to initialize and mount SPIFFS filesystem.
// Note: esp_vfs_spiffs_register is an all-in-one convenience function.
//初始化上面的结构体
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
ESP_LOGE(TAG, "Failed to mount or format filesystem");
}
else if (ret == ESP_ERR_NOT_FOUND)
{
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
}
else
{
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
}
return;
}
// 检查文件系统的状态
#ifdef CONFIG_EXAMPLE_SPIFFS_CHECK_ON_START
ESP_LOGI(TAG, "Performing SPIFFS_check().");
ret = esp_spiffs_check(conf.partition_label);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "SPIFFS_check() failed (%s)", esp_err_to_name(ret));
return;
}
else
{
ESP_LOGI(TAG, "SPIFFS_check() successful");
}
#endif
size_t total = 0, used = 0;
ret = esp_spiffs_info(conf.partition_label, &total, &used); // 获取SPIFFS的总容量和已使用的容量
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s). Formatting...", esp_err_to_name(ret));
esp_spiffs_format(conf.partition_label); // 格式化SPIFFS
return;
}
else
{
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
}
//如果已经使用的大于总的则进行一致性检查
// Check consistency of reported partiton size info.
if (used > total)
{
ESP_LOGW(TAG, "Number of used bytes cannot be larger than total. Performing SPIFFS_check().");
ret = esp_spiffs_check(conf.partition_label);
// Could be also used to mend broken files, to clean unreferenced pages, etc.
// More info at https://github.com/pellepl/spiffs/wiki/FAQ#powerlosses-contd-when-should-i-run-spiffs_check
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "SPIFFS_check() failed (%s)", esp_err_to_name(ret));
return;
}
else
{
ESP_LOGI(TAG, "SPIFFS_check() successful");
}
}
}
SPIFFS文件测试
void Spiffs_test(void)
{
// Use POSIX and C standard library functions to work with files.
// First create a file.
ESP_LOGI(TAG, "Opening file");
FILE *f = fopen("/spiffs/hello.txt", "w"); // 打开/创建文件
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "Hello World!\n"); // 写入文件
fclose(f);
ESP_LOGI(TAG, "File written");
// Check if destination file exists before renaming(在重命名前检查目标文件是否存在)
struct stat st;
if (stat("/spiffs/foo.txt", &st) == 0)
{
// Delete it if it exists
unlink("/spiffs/foo.txt");
}
// Rename original file(重命名文件)
ESP_LOGI(TAG, "Renaming file");
if (rename("/spiffs/hello.txt", "/spiffs/foo.txt") != 0)
{
ESP_LOGE(TAG, "Rename failed");
return;
}
// Open renamed file for reading(打开重命名文件)
ESP_LOGI(TAG, "Reading file");
f = fopen("/spiffs/foo.txt", "r");
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
char line[64];
fgets(line, sizeof(line), f); // 打开f文件,读取大小为line的数据,并存放到数组line中
fclose(f);
// strip newline
char *pos = strchr(line, '\n'); // 查找第一个换行符的位置,若有则返回其位置
if (pos)
{
*pos = '\0';
}
ESP_LOGI(TAG, "Read from file: '%s'", line);
}
禁用SPIFFS文件系统
void Spiffs_deinit(void)
{
// All done, unmount partition and disable SPIFFS(卸载分区,禁用SPIFFS)
esp_vfs_spiffs_unregister(conf.partition_label);
ESP_LOGI(TAG, "SPIFFS unmounted");
}
项目代码
https://github.com/Holay888/DeskScreen/tree/demo2