SPIFFS opens file but reads no data

I am trying to use spiffs to store an html file but I can’t seem to fread from it. The set up as well as fopen works, but fread returns 0.

My Partition Table

# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x10000,  0x6000
otadata,  data, ota,     0x16000,  0x2000
phy_init, data, phy,     0x18000,  0x1000
ota_0,    0,    ota_0,   0x20000,  1500K
ota_1,    0,    ota_1,   ,         1500K
storage,  data, nvs,     ,         0x10000
spiffs,  data, spiffs,   0x327000, 0x30000

sdkconfig

#
# SPIFFS Configuration
#
CONFIG_SPIFFS_MAX_PARTITIONS=3

#
# SPIFFS Cache Configuration
#
CONFIG_SPIFFS_CACHE=y
CONFIG_SPIFFS_CACHE_WR=y
CONFIG_SPIFFS_CACHE_STATS=
CONFIG_SPIFFS_PAGE_CHECK=y
CONFIG_SPIFFS_GC_MAX_RUNS=10
CONFIG_SPIFFS_GC_STATS=
CONFIG_SPIFFS_PAGE_SIZE=256
CONFIG_SPIFFS_OBJ_NAME_LEN=32
CONFIG_SPIFFS_USE_MAGIC=y
CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
CONFIG_SPIFFS_META_LENGTH=4
CONFIG_SPIFFS_USE_MTIME=y

#
# Debug Configuration
#
CONFIG_SPIFFS_DBG=
CONFIG_SPIFFS_API_DBG=
CONFIG_SPIFFS_GC_DBG=
CONFIG_SPIFFS_CACHE_DBG=
CONFIG_SPIFFS_CHECK_DBG=
CONFIG_SPIFFS_TEST_VISUALISATION=

Steps I took

./mkspiffs -c ./components/wifi/resources -b 4096 -p 256 -s 0x30000 spiffs.bin

./components/wifi/resources has two files in it, a .txt and a .html

python ./amazon-freertos/vendors/espressif/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART --baud 115200 write_flash -z 0x327000 spiffs.bin

The code:

esp_err_t init_spiffs(){
    esp_vfs_spiffs_conf_t conf = {
            .base_path = "/spiffs",
            .partition_label = NULL,
            .max_files = 5,
            .format_if_mount_failed = true
    };

    // 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(MAIN, "Failed to mount or format filesystem");
        } else if (ret == ESP_ERR_NOT_FOUND) {
            ESP_LOGE(MAIN, "Failed to find SPIFFS partition");
        } else {
            ESP_LOGE(MAIN, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
        }
        return ret;
    }

    size_t total = 0, used = 0;
    ret = esp_spiffs_info(NULL, &total, &used);
    if (ret != ESP_OK) {
        ESP_LOGE(MAIN, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
    } else {
        ESP_LOGI(MAIN, "Partition size: total: %d, used: %d", total, used);
    }
    return ESP_OK;
}
...
int app_main( void ){
    // Initialize SPIFFS
    ret = init_spiffs();
    if(ret != ESP_OK){
        ESP_LOGI(MAIN, "init_spiffs(): %s", esp_err_to_name(ret));
        return 0;
    }

    ESP_LOGI(MAIN, "Opening file");
    FILE* f = fopen("/spiffs/foo.txt", "r");
    if (f == NULL) {
        ESP_LOGI(MAIN, "Failed to open file for writing");
    }

    char buf[100] = {0};
    int bytes_read = fread(buf, 1, 100, f);
    ESP_LOGI(MAIN, "bytes read: %i", bytes_read);
    for(int i = 0; i < 100; i++){
        printf("%c\n", buf[i]);
    }

Console output:

I (340) MAIN: Partition size: total: 173441, used: 28614
I (340) MAIN: Opening file
I (340) MAIN: bytes read: 0

Any help would be appreciated. Thanks!

SPIFFS is not a library we use in any of our examples that I know of. Did you do the integration yourself or are using using integrations provided elsewhere? If the latter I would suggest asking the question wherever you obtained the code from originally.

1 Like

Oh ya I mistakenly thought it was from FreeRTOS but its from Espressif. Thanks!

@isnore, I’ve moved this thread to the Espressif category so that members of the @Espressif team can answer this question for you.

1 Like

@isnore Can you please check ./mkspiffs --version output against the config options (from sdkconfig) you provided above? Thread at https://github.com/espressif/esp-idf/issues/1732 can help you further.

1 Like

Here is the output from:

./mkspiffs --version
mkspiffs ver. 0.2.3
Build configuration name: esp-idf
SPIFFS ver. 0.3.7-5-gf5e26c4
Extra build flags: -DSPIFFS_OBJ_META_LEN=4
SPIFFS configuration:
  SPIFFS_OBJ_NAME_LEN: 32
  SPIFFS_OBJ_META_LEN: 4
  SPIFFS_USE_MAGIC: 1
  SPIFFS_USE_MAGIC_LENGTH: 1
  SPIFFS_ALIGNED_OBJECT_INDEX_TABLES: 0

sdkconfig

#
# SPIFFS Configuration
#
CONFIG_SPIFFS_MAX_PARTITIONS=3

#
# SPIFFS Cache Configuration
#
CONFIG_SPIFFS_CACHE=y
CONFIG_SPIFFS_CACHE_WR=y
CONFIG_SPIFFS_CACHE_STATS=
CONFIG_SPIFFS_PAGE_CHECK=y
CONFIG_SPIFFS_GC_MAX_RUNS=10
CONFIG_SPIFFS_GC_STATS=
CONFIG_SPIFFS_PAGE_SIZE=256
CONFIG_SPIFFS_OBJ_NAME_LEN=32
CONFIG_SPIFFS_USE_MAGIC=y
CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
CONFIG_SPIFFS_META_LENGTH=4
CONFIG_SPIFFS_USE_MTIME=y

#
# Debug Configuration
#
CONFIG_SPIFFS_DBG=
CONFIG_SPIFFS_API_DBG=
CONFIG_SPIFFS_GC_DBG=
CONFIG_SPIFFS_CACHE_DBG=
CONFIG_SPIFFS_CHECK_DBG=
CONFIG_SPIFFS_TEST_VISUALISATION=

@isnore I created two files a.html and a.txt with the same folder structure. fread() worked for me. Here is the code I used:

ESP_LOGI(TAG, "Reading file");
FILE* f = fopen("/spiffs/a.html", "r");
if (f == NULL) {
    ESP_LOGE(TAG, "Failed to open file for reading");
    return;
}
char line[300] = {0};
int bytes_read = fread(line, 1, 300, f);
ESP_LOGI(TAG, "bytes read: %i", bytes_read);
printf("\n\n%s\n", line);
fclose(f);

Can you run the command ./mkspiffs -l spiffs.bin and share the output.

You can also unpack the generated image using ./mkspiffs -u <dest_dir> spiffs.bin and verify contents of the files.

./mkspiffs -l spiffs.bin output

27797   /capture_portal.html
30      /foo.txt

When I unpack the spiffs.bin I do see the two files with the correct content.

I ran the following code:

    // Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        nvs_flash_init();
    }

    // Initialize SPIFFS
    ret = init_spiffs();
    if(ret != ESP_OK){
        ESP_LOGI(MAIN, "init_spiffs(): %s", esp_err_to_name(ret));
        return 0;
    }

    ESP_LOGI(MAIN, "Opening file");
    char line[300] = {0};

    FILE* f = fopen("/spiffs/foo.txt", "r");

    if (f == NULL) {
        ESP_LOGE(MAIN, "Failed to open file for reading");
        return -1;
    }

    int bytes_read = fread(line, 1, 300, f);
    ESP_LOGI(MAIN, "bytes read: %i", bytes_read);

    printf("\n\n%s\n", line);
    fclose(f);

resulting in the following output:

I (887) MAIN: Partition size: total: 173441, used: 28865
I (887) MAIN: Opening file
I (897) MAIN: bytes read: 0




Is there some sort of configuration option I need to change? Please have a look at the sdkconfig I provided above? I read something about changing the meta data length field.

Update

I am able to create a file, write to it, and read back from it. But still can’t access files I flashed to the board. See code and output below:

// Initialize SPIFFS
    ret = init_spiffs();
    if(ret != ESP_OK){
        ESP_LOGI(MAIN, "init_spiffs(): %s", esp_err_to_name(ret));
        return 0;
    }

    ESP_LOGI(MAIN, "Opening file");
    char line[300] = {0};

    FILE* f = fopen("/spiffs/hello.txt", "w");

    if (f == NULL) {
        ESP_LOGE(MAIN, "Failed to open file for reading");
        return -1;
    }
    fprintf(f, "Hello World!\n");
    fclose(f);

    f = fopen("/spiffs/hello.txt", "r");

    if (f == NULL) {
        ESP_LOGE(MAIN, "Failed to open file for reading");
        return -1;
    }

    int bytes_read = fread(line, 1, 300, f);
    ESP_LOGI(MAIN, "bytes read: %i", bytes_read);

    printf("\n\n%s\n", line);
    fclose(f);

Output:

I (887) MAIN: Partition size: total: 173441, used: 29367
I (887) MAIN: Opening file
I (897) MAIN: bytes read: 13


Hello World!


I used esptool.py to read the flash from the esp32 and noticed something interesting.

Ran the following commands:

python3 /Users/vp/esp/Pebble_ESP32_Firmware/amazon-freertos/vendors/espressif/esp-idf/components/esptool_py/esptool/esptool.py --port /dev/cu.SLAB_USBtoUART --baud 115200 read_flash 0x327000 0x30000 flash_conetents.bin
./mkspiffs -u . flash_conetents.bin

and the hello.txt I made in code had weird byte values and its hex was:
EFBFBDEF BFBD3DEF BFBDEFBF BD7F0000 EFBFBD73 EFBFBD6A EFBFBD

but the other files, like foo.txt unloaded and were the as when they were flashed.

Solution

Got it working! Make sure you have the following sdkconfig option:

CONFIG_SPIFFS_META_LENGTH=4

mine was 0 and did not work.