Chat freely about anything...

User avatar
By Inq720
#92497 I too have never experienced any flash errors with an ESP8266 (out of a hundred or so I've used). But... with memory updates of only one every thirty minutes, you shouldn't have. Even with the pessimistic, expected life found on the Internet, you shouldn't see an error for a few years and if my chip is really indicative, more like a couple decades.

I'm certainly aware there is no built-in error detection. I would like to find out and write my own. If it is as you suggest - the whole sector becomes bad, then there is no practical remedy. If its only certain locations in the sector as I suspect, then I can/will write some avoidance code.

However, on the slowing down... I thought and read the same as you; however, this appears to be mistaken. The flash chip on this ESP8266 - ESP01 IS slowing down due to use. The attached graph is the on-going test. Unless... you can suggest some other influence in the attached test code to make it look like its slowing down. ;)

Code: Select all#include <spi_flash.h>
#include <user_interface.h>

#define EEPROM_OFFSET -5
const u16 MAX = SPI_FLASH_SEC_SIZE;        // in Bytes
u32 array[MAX / sizeof(u32)];
u16 sector;
u32 location;
u32 count;

void check(SpiFlashOpResult rslt, const char* msg)
{
    if (rslt != SPI_FLASH_RESULT_OK)
    {
        Serial.printf("%s[%u] error = %u\n", msg, count, rslt);
        while(true) delay(1000);
    }
}

u16 mapSector(s16 sectorOffset)
{
    // If sectorOffset >= 0, we are doing relative to the beginning.
    // If sectorOffset <  0, we are doing realtive to the end.
    // Last 4 sectors are System.
    // 5th back from end is "EEPROM" area.
    u32 sec;
    flash_size_map map = system_get_flash_size_map();
    switch (map)
    {
        case FLASH_SIZE_4M_MAP_256_256:     sec = 128;  break;
        case FLASH_SIZE_2M:                 sec = 0;    break;
        case FLASH_SIZE_8M_MAP_512_512:     sec = 256;  break;
        case FLASH_SIZE_16M_MAP_512_512:    sec = 512;  break;
        case FLASH_SIZE_32M_MAP_512_512:    sec = 1024; break;
        case FLASH_SIZE_16M_MAP_1024_1024:  sec = 512;  break;
        case FLASH_SIZE_32M_MAP_1024_1024:  sec = 1024; break;
        case FLASH_SIZE_64M_MAP_1024_1024:  sec = 2048; break;
        case FLASH_SIZE_128M_MAP_1024_1024: sec = 4096; break;
    }
    if (sectorOffset < 0)
        sectorOffset = sec + sectorOffset;
    return sectorOffset;
}

void setup()
{
   Serial.begin(115200);
   while(!Serial) { Serial.print("."); delay(100); }
   delay(2000);
   Serial.println("\nStarting ------------------------ ");

    sector = mapSector(EEPROM_OFFSET);
    location = sector * SPI_FLASH_SEC_SIZE;   
   
    check(spi_flash_read(location, array, MAX), "Init Read");
   
    count = array[0];
    if (count > (u32)-10)
        count = 0;
    Serial.printf("Test starts at %u\n", count);
   
   Serial.println("Started");   
}

#define INTERVAL 3600000

void loop()
{
    static u32 loops = 0;
    loops++;
   
    static u32 last = millis();
    u32 now = millis();
    if (now - last > INTERVAL)
    {
        u32 div = INTERVAL / 1000;
        Serial.printf("Count=%u  Rate=%f\n", count, (float)loops / (float)div);
        last = now;
        loops = 0;
    }
   
    count++;

    // Erase It
    check(spi_flash_erase_sector(sector), "Erase");

    // Write It
    for(int i=0; i<MAX / sizeof(u32); i++)
        array[i] = count;
    check(spi_flash_write(location, array, MAX), "Write");

    // Read It Back In
    check(spi_flash_read(location, array, MAX), "Read");
   
    // Check It
    SpiFlashOpResult rslt = SPI_FLASH_RESULT_OK;
    for(int i=0; i<MAX / sizeof(u32); i++)
    {
        if (array[i] != count)
        {
            if (rslt == SPI_FLASH_RESULT_OK)
                Serial.printf("Verification[%u]\n", count);

            Serial.printf("Memory error @ %u\n", i);
            rslt = SPI_FLASH_RESULT_ERR;
        }
    }
    check(rslt, "Valid");
}
Attachments
Capture.PNG
Graph of flash chip slowing
User avatar
By Inq720
#92500 Its really hard to draw any real conclusions from just one data point. But, someone might find this useful some day.

The FIRST test of writing erasing/writing/reading/validating a one sector full 4K sector has finished.

As I only had it printing out every hour to the serial monitor, I can't get a final tally. I expected to be able to have the flash tell me what the final number as that was what I wrote in all 4K was the tally. BUT, not only is the flash sector trashed, the whole ESP8266-ESP01 is trashed. This is its final words before giving up the ghost...


Count=670914 Rate=3.982222
Count=684722 Rate=3.835556

ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset


It won't restart and trying to compile/upload won't take either.

I've broken out a second ESP01 and am serving it up to the gods. At least I'll have two data points. :lol:
User avatar
By eriksl
#92504 Uploading new firmware, at least the part where it connects to the ESP8266, is always possible, even if no flash is connected at all. If even that doesn't succeed, your ESP8266 is dead, not the flash chip. You may want to try to read the mac address for example, to check.

If the flash is the culprit and it won't start, it looks like one of the first sectors is actually damaged. I can't imagine all sectors have gone bad at the same time.
User avatar
By Inq720
#92507 I definitely want to pursue your suggestions. I only have the one ESP01 programmer at the moment and its running test #3. I have two more ordered, expected to arrive Monday.

I just compiled a WeMos to see what you might be describing. Most of the time I've never really paid attention to the verbiage on the console. I do remember after that first ESP01 failed, I was able to compile and the console output did get to the point of the writing lines, paused, then puked out a bunch of error detail (which I don't recall). But I see on the WeMos, the MAC is before that point and I assume the bad ESP01 did get that far and had a valid MAC.
I will re-hook it up after the current test finishes and explore some more.

TEST 2 COMPLETED
The second ESP01 failed in the same manner. Meaning, I never saw any SPI_FLASH_RESULT_ERR or
SPI_FLASH_RESULT_TIMEOUT returned from any of the Espressif functions. I also didn't get any validation errors. It simply failed with the same:

Count=438809 Rate=4.126667
Count=440918 Rate=3.515000
Count=443277 Rate=3.931667
Count=445551 Rate=3.790000


ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset

As seen above it did pass through 445551 and did exhibit the same slowing as the memory got used.

TEST 3 - One difference with this ESP01... it allowed me to set my code to another sector, compile, upload and start a new test. As the other two tests, it start at a rate above 20Hz and is slowing. Currently around 60,000 cycles, it's already down below 16 Hz. When this test finishes, I'll try to inspect both ESP01s some more.
Attachments
test2.PNG