espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.36k stars 7.21k forks source link

esp32-powerdown-spiffs failed to erase addr (IDFGH-6035) #7720

Closed 6331wangzhijun closed 2 years ago

6331wangzhijun commented 2 years ago

when the esp32 write data. power off is happen suddenly. we want to test the esp32 stability. when it happen. the esp32 can work ok. But in fact after test some time. spiffs failed. and the system can not continue.

the sdk is 4.2.1 release 1:use spiffs_example_main.c. 2:Use a task to write data to spiffs in loop; 3:in main task, after 3 second, power off the esp32 ,then power on esp32; 4:test half an hour or more. when the system power on again will print SPIFFS: failed to erase add ..... .the system will stop continue;

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:4 load:0x3fff0034,len:7112 load:0x40078000,len:13212 load:0x40080400,len:4640 0x40080400: _init at ??:?

entry 0x400806fc I (29) boot: B2C ESP-IDF bddfdc9-dirty 2nd stage bootloader add led I (29) boot: compile time 15:21:17 I (29) boot: chip revision: 1 I (34) boot_comm: chip revision: 1, min. bootloader chip revision: 0 I (41) boot.esp32: SPI Speed : 40MHz I (45) boot.esp32: SPI Mode : DIO I (50) boot.esp32: SPI Flash Size : 8MB I (54) boot: Enabling RNG early entropy source... I (60) boot: Partition Table: I (63) boot: ## Label Usage Type ST Offset Length I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (86) boot: 2 factory factory app 00 00 00010000 00100000 I (93) boot: 3 storage Unknown data 01 82 00110000 00300000 I (101) boot: End of partition table I (105) boot_comm: chip revision: 1, min. application chip revision: 0 I (112) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x07420 ( 29728) map I (132) esp_image: segment 1: paddr=0x00017448 vaddr=0x3ffb0000 size=0x023f8 ( 9208) load I (136) esp_image: segment 2: paddr=0x00019848 vaddr=0x40080000 size=0x00404 ( 1028) load 0x40080000: _WindowOverflow4 at D:/gitEspCode/esp-idf-v4.2.1/components/freertos/xtensa/xtensa_vectors.S:1730

I (141) esp_image: segment 3: paddr=0x00019c54 vaddr=0x40080404 size=0x063c4 ( 25540) load I (161) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x19e28 (106024) map 0x400d0020: _stext at ??:?

I (202) esp_image: segment 5: paddr=0x00039e50 vaddr=0x400867c8 size=0x04280 ( 17024) load 0x400867c8: vTaskPriorityInherit at D:/gitEspCode/esp-idf-v4.2.1/components/freertos/tasks.c:4074

I (216) boot: Loaded app from partition at offset 0x10000 I (216) boot: Disabling RNG early entropy source... I (216) cpu_start: Pro cpu up. I (220) cpu_start: Application information: I (225) cpu_start: Project name: spiffs I (229) cpu_start: App version: bddfdc9-dirty I (235) cpu_start: Compile time: Oct 14 2021 15:21:52 I (241) cpu_start: ELF file SHA256: db680773cb99b7b6... I (247) cpu_start: ESP-IDF: bddfdc9-dirty I (252) cpu_start: Starting app cpu, entry point is 0x40081620 0x40081620: call_start_cpu1 at D:/gitEspCode/esp-idf-v4.2.1/components/esp32/cpu_start.c:287

I (0) cpu_start: App cpu up. I (263) heap_init: Initializing. RAM available for dynamic allocation: I (270) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (276) heap_init: At 3FFB2C40 len 0002D3C0 (180 KiB): DRAM I (282) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (288) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (295) heap_init: At 4008AA48 len 000155B8 (85 KiB): IRAM I (301) cpu_start: Pro cpu start user code I (319) spi_flash: detected chip: gd I (320) spi_flash: flash io: dio I (320) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. I (328) example-spiffs: Initializing SPIFFS E (518) SPIFFS: failed to erase addr 00005000, size 00001000, err 261 E (518) SPIFFS: failed to write addr 000050fe, size 00000002, err 261 W (518) SPIFFS: mount failed, -1. formatting... E (528) SPIFFS: failed to erase addr 00000000, size 00001000, err 261 E (538) SPIFFS: failed to write addr 000000fe, size 00000002, err 261 E (538) SPIFFS: format failed, -10027 E (548) example-spiffs: Failed to mount or format filesystem

5:the normal power on print is: rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:4 load:0x3fff0034,len:7112 load:0x40078000,len:13212 load:0x40080400,len:4640 0x40080400: _init at ??:?

entry 0x400806fc I (29) boot: B2C ESP-IDF bddfdc9-dirty 2nd stage bootloader add led I (29) boot: compile time 15:21:17 I (29) boot: chip revision: 1 I (34) boot_comm: chip revision: 1, min. bootloader chip revision: 0 I (41) boot.esp32: SPI Speed : 40MHz I (45) boot.esp32: SPI Mode : DIO I (50) boot.esp32: SPI Flash Size : 8MB I (54) boot: Enabling RNG early entropy source... I (60) boot: Partition Table: I (63) boot: ## Label Usage Type ST Offset Length I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (86) boot: 2 factory factory app 00 00 00010000 00100000 I (93) boot: 3 storage Unknown data 01 82 00110000 00300000 I (101) boot: End of partition table I (105) boot_comm: chip revision: 1, min. application chip revision: 0 I (112) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x07420 ( 29728) map I (132) esp_image: segment 1: paddr=0x00017448 vaddr=0x3ffb0000 size=0x023f8 ( 9208) load I (136) esp_image: segment 2: paddr=0x00019848 vaddr=0x40080000 size=0x00404 ( 1028) load 0x40080000: _WindowOverflow4 at D:/gitEspCode/esp-idf-v4.2.1/components/freertos/xtensa/xtensa_vectors.S:1730

I (141) esp_image: segment 3: paddr=0x00019c54 vaddr=0x40080404 size=0x063c4 ( 25540) load I (161) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x19e28 (106024) map 0x400d0020: _stext at ??:?

I (202) esp_image: segment 5: paddr=0x00039e50 vaddr=0x400867c8 size=0x04280 ( 17024) load 0x400867c8: vTaskPriorityInherit at D:/gitEspCode/esp-idf-v4.2.1/components/freertos/tasks.c:4074

I (216) boot: Loaded app from partition at offset 0x10000 I (216) boot: Disabling RNG early entropy source... I (216) cpu_start: Pro cpu up. I (220) cpu_start: Application information: I (225) cpu_start: Project name: spiffs I (229) cpu_start: App version: bddfdc9-dirty I (235) cpu_start: Compile time: Oct 14 2021 15:21:52 I (241) cpu_start: ELF file SHA256: db680773cb99b7b6... I (247) cpu_start: ESP-IDF: bddfdc9-dirty I (252) cpu_start: Starting app cpu, entry point is 0x40081620 0x40081620: call_start_cpu1 at D:/gitEspCode/esp-idf-v4.2.1/components/esp32/cpu_start.c:287

I (0) cpu_start: App cpu up. I (263) heap_init: Initializing. RAM available for dynamic allocation: I (270) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (276) heap_init: At 3FFB2C40 len 0002D3C0 (180 KiB): DRAM I (282) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (288) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (295) heap_init: At 4008AA48 len 000155B8 (85 KiB): IRAM I (301) cpu_start: Pro cpu start user code I (319) spi_flash: detected chip: gd I (320) spi_flash: flash io: dio I (320) cpu_start: Starting scheduler on PRO CPU. I (0) cpu_start: Starting scheduler on APP CPU. I (328) example-spiffs: Initializing SPIFFS I (648) example-spiffs: Partition size: total: 2884241, used: 39909 I (648) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 W (658) example-spiffs: gpio 13 low

E (658) example-spiffs: gpio 13 low!!!!!!!!!!!!!!!!!!!!!!

write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! write 120 data successed! I (3868) example-sp ��.'H�� R�&$ZZ-�C��+L[C�ets Jun 8 2016 00:22:57

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:4 load:0x3fff0034,len:7112 load:0x40078000,len:13212 load:0x40080400,len:4640

zztiger123 commented 2 years ago

Hi 6331wangzhijun,

SPIFFS support some sort of power-off safety by design, so the file system can be fixed by calling SPIFFS_check() API function. The function is time-consuming and is not involved in standard mount. I'm afraid it works up to some extent and it's not guaranteed it fixes very type of failure, however, it's the only available option. more details here https://github.com/pellepl/spiffs/wiki/FAQ

For example: if the rst reason is ESP_RST_UNKNOWN or ESP_RST_BROWNOUT, you should add the following type of check into their application: esp_reset_reason reason = esp_reset_reason();

if( reason == ESP_RST_UNKNOWN || reason == ESP_RST_BROWNOUT) SPIFFS_check(fs);

where fs is the SPIFFS file system instance.

We observe that the reason for your rst is RTCWDT_RTC_RESET, so you can run the SPIFFS_check() on every mount failure-that's probably the best solution which covers also other errors

6331wangzhijun commented 2 years ago

Hi Thanks for your answer. I will use spiffs_check function to check. but I find it used in test case. and need fs . How can i use spiffs_check in my api code?

adokitkat commented 2 years ago

Hello 6331wangzhijun,

For now I've made some changes and a git patch for your IDF version (v4.2.1) which you can unzip and apply in esp-idf repository via git apply esp_spiffs_check.patch.

esp_spiffs_check.patch.zip

Then there will be a new function esp_spiffs_check() exposed to you which you can use in your code as following:

esp_spiffs_check("partition label");

However as it was already said it is not guaranteed it will fix your problem so you'll have to try it out for yourself.

For other IDF versions you can manually add these pieces of code to:

esp_err_t esp_spiffs_check(const char* partition_label)
{
    int index;
    if (esp_spiffs_by_label(partition_label, &index) != ESP_OK) {
        return ESP_ERR_INVALID_STATE;
    }
    if (SPIFFS_check(_efs[index]->fs) != SPIFFS_OK) {
        return ESP_FAIL;
    }
    return ESP_OK;
}
/**
 * Check integrity of SPIFFS
 *
 * @param partition_label  Same label as passed to esp_vfs_spiffs_register
 * @return  
 *          - ESP_OK                  if successful
 *          - ESP_ERR_INVALID_STATE   if not mounted
 *          - ESP_FAIL                on error
 */
esp_err_t esp_spiffs_check(const char* partition_label);
6331wangzhijun commented 2 years ago

Hi Zombie, Adam M Thannks . I have put your spiffs patch in my code, and test it. There is error message still happen(SPIFFS: failed to write addr), and the spiffs is mount ok:

I (328) example-spiffs: Initializing SPIFFS I (648) example-spiffs: Partition size: total: 2884241, used: 28865 W (658) example-spiffs: esp reset reson is:7 I (648) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 W (658) example-spiffs: gpio 13 low

E (700) SPIFFS: failed to write addr 00062200, size 00000100, err 261 GwlogWrite Failed to open file for writing

My write data code is: static int GwLogWrite(char input_value) { FILE fpSource = NULL; int size = -1; int fd = -1; int write_len =0; int ret =0; fpSource = fopen(LOG_FILE_PATH,"w+"); if (!fpSource) {

printf("%s Failed to open file for writing\n",func);

    //close(fd);
    return -1;
}

... }

adokitkat commented 2 years ago

Hello again.

Unfortunately I have not been able to reproduce your issue even with the code you provided. I had it running for hours but there was no error. I will attach my code at the end for you to compare it with yours. Maybe there was a misunderstanding and I didn't follow the exact procedure.

I also have a few questions:

This is an example code I used based on your comment:

/* SPIFFS filesystem example.
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_spiffs.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_timer.h"

static const char *TAG = "example";

static int GwLogWrite()
{
    FILE *fp = NULL;
    fp = fopen("/spiffs/file.txt","w+");
    if (!fp)
    {
        printf("Failed to open file for writing\n");
        return -1;
    }
    fprintf(fp, "A\n");

    fclose(fp);
    return 0;
}

void app_main(void)
{
    ESP_LOGI(TAG, "Initializing 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(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

    ESP_LOGI(TAG, "Start of logging...");
    int64_t init = esp_timer_get_time();
    ESP_LOGI(TAG, "Timer init: %lld", init);
    int64_t now = 0;
    int log_ret = 0;
    while(true)
    {
        log_ret = GwLogWrite();
        if (log_ret == -1) {
            ESP_LOGE(TAG, "GwLogWrite() error");
            return;
        }
        now = esp_timer_get_time();
        if ((now - init) >= 3000000) {
            break;
        }
    }
    ESP_LOGI(TAG, "End of logging. Restart...");

    // All done, unmount partition and disable SPIFFS
    esp_vfs_spiffs_unregister(conf.partition_label);
    ESP_LOGI(TAG, "SPIFFS unmounted");
    esp_restart();
}
adokitkat commented 2 years ago

I am closing this issue due to no response. Feel free to reopen when needed.