主要参考资料:
B站up主小桃今天不摆烂《介绍Esp的闪存spiffs》
B站up主第九个下弦月《ESP32-IDF lvgl gif解码基于文件系统 spiffs移植 (包含如何移植spiffs)(第三节)》
乐鑫官网spiffs链接: https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/storage/spiffs.html#id4
Github里spiffs仓库链接: https://github.com/pellepl/spiffs
spiffs简介
下面是spiffs的一个简单介绍:
1.首先,spiffs是专门为低RAM而设计的。以ESP32-S3为例,不算上PSRAM,仅有512k的SRAM。
3.这里注意它是一个类posix接口,在menuconfig lvgl配置时遇到过对多种接口的选择。
4.NOR是逻辑门电路中的“或非”门,与之相对应的是NAND“与非门”。NOR Flash的非易失性、超高读取速度、可片上执行、写入速度慢以及价格昂贵等独特的特性决定了NOR Flash不适合做大容量存储。
1.这里说spiffs只有一级目录,比如创建/spiffs/tmp/myfile.txt不会新增tmp目录,而是文件名叫tmp/myfile.txt
2.这是几个文件系统的速度对比。
基于ESP-IDF的spiffs移植
初始化代码
#include <stdint.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_spiffs.h"
esp_vfs_spiffs_conf_t conf = {
.base_path = mount_point,
.partition_label = partition_label,
.max_files = max_files,
.format_if_mount_failed = false,
};
esp_err_t ret_val = esp_vfs_spiffs_register(&conf);
if (ESP_OK != ret_val) {
return ret_val;
}
size_t total = 0, used = 0;
ret_val = esp_spiffs_info(conf.partition_label, &total, &used);
if (ret_val != ESP_OK) {
ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret_val));
} else {
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
}
读取spiffs文件
static void read_hello_txt(void)
{
ESP_LOGI(TAG, "Reading hello.txt");
// Open for reading hello.txt
FILE* f = fopen("/spiffs/hello.txt", "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open hello.txt");
return;
}
char buf[64];
memset(buf, 0, sizeof(buf));
fread(buf, 1, sizeof(buf), f);
fclose(f);
// Display the read contents from the file
ESP_LOGI(TAG, "Read from hello.txt: %s", buf);
}
CMakeLists.txt文档
idf_component_register(SRCS “spiffsgen_example_main.c”
INCLUDE_DIRS “.”)
/* 从’spiffs_image’目录的内容创建一个SPIFFS映像,该映像对应partition_table中名为’storage’的分区。FLASH_IN_PROJECT表示当使用’idf.py -p PORT flash’将整个项目刷新到目标时,应该刷新生成的映像。 */
spiffs_create_partition_image(storage …/spiffs_image FLASH_IN_PROJECT)
计算md5哈希值
static void compute_alice_txt_md5(void)
{
ESP_LOGI(TAG, "Computing alice.txt MD5 hash");
// The file alice.txt lives under a subdirectory, though SPIFFS itself is flat
FILE* f = fopen("/spiffs/sub/alice.txt", "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open alice.txt");
return;
}
// Read file and compute the digest chunk by chunk
#define MD5_MAX_LEN 16
char buf[64];
mbedtls_md5_context ctx;
unsigned char digest[MD5_MAX_LEN];
mbedtls_md5_init(&ctx);
mbedtls_md5_starts_ret(&ctx);
size_t read;
do {
read = fread((void*) buf, 1, sizeof(buf), f);
mbedtls_md5_update_ret(&ctx, (unsigned const char*) buf, read);
} while(read == sizeof(buf));
mbedtls_md5_finish_ret(&ctx, digest);
// Create a string of the digest
char digest_str[MD5_MAX_LEN * 2];
for (int i = 0; i < MD5_MAX_LEN; i++) {
sprintf(&digest_str[i * 2], "%02x", (unsigned int)digest[i]);
}
// For reference, MD5 should be deeb71f585cbb3ae5f7976d5127faf2a
ESP_LOGI(TAG, "Computed MD5 hash of alice.txt: %s", digest_str);
fclose(f);
}