esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.07k stars 13.33k forks source link

Updater class corrupting FS uploads by setting flash mode byte in 1st sector #6880

Closed mike-s123 closed 4 years ago

mike-s123 commented 4 years ago

Basic Info

Platform

Settings in IDE

Problem Description

Uploading a large (~14MB) LittleFS image via ESP8266HTTPUpdateServer doesn't work (i.e. LittleFS.open() fails and the sketch can not open/read files).

Uploading the same image using USB and esptool.py (either manually or with the IDE uploader) works fine. Then, uploading the same image using OTA causes failure.

With an identically sized SPIFFs image, both USB and OTA uploads work fine. OTA firmware uploads work fine.

This has been 100% repeatable.

using esptool.py (this works, OTA doesn't)

$ esptool.py --before default_reset --after hard_reset -p COM10 --baud 921600 write_flash 0x200000 FS.mklittlefs.bin
esptool.py v2.6
Serial port COM10
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: xxxx
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 16MB
Compressed 14655488 bytes to 1038072...
Wrote 14655488 bytes (1038072 compressed) at 0x00200000 in 42.1 seconds (effective 2784.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
earlephilhower commented 4 years ago

Can you try with spiffs, too? Should be the same, as far as the uploader knows it's just bits.

mike-s123 commented 4 years ago

As stated, SPIFFs (and firmware) uploads work just fine.

mike-s123 commented 4 years ago

@earlephilhower Update. I created a simple program to dump the first 16 bytes of the flash starting at 0x200000, where the filesystem starts. The upload using esptool.py exactly matches the original file. The upload using ESP8266HTTPUpdateServer had corrupted the first few bytes (specifically, it set the third byte to 2 when it was originally 0):

Good (esptool.py):
Successfully mounted LittleFS
spi_flash_read result :0
read0:1
read1:f7ff0ff0
read2:7474696c
read3:7366656c

Bad (OTA):
An Error has occurred while mounting LittleFS
spi_flash_read result :0
read0:20001   
read1:f7ff0ff0
read2:7474696c
read3:7366656c

File (note that due to "endedness", byte order is reversed compared to what's shown above):
Generated by HexEdit
00000000  01 00 00 00 f0 0f ff f7 6c 69 74 74 6c 65 66 73  ....ð.ÿ÷littlefs
earlephilhower commented 4 years ago

Very strange indeed. Have you uploaded a smaller FS (say, 1M)? I'm thinking if it's data corruption like that, then the FS size itself would not impact things. Might also be the Updater patching in something that it shouldn't (like it does when patching in ROM size in app images).

earlephilhower commented 4 years ago

https://github.com/esp8266/Arduino/blob/a738884387bbdb7cecfa30fdbebe6a162d17bc76/cores/esp8266/Updater.cpp#L326-L347

Looks like the Updater class is always potentially corrupting the first sector of a FS upload. SPIFFS doesn't check its structures very much (if at all) when mounting, so it might just ignore this.

The flashmode change update needs to be predicated on !U_FS.

mike-s123 commented 4 years ago

@earlephilhower

Configured as a Lolin D1 (4MB flash), with FS:2MB, which I'd expect to be a common config for a more common board, since it should allow OTA updates for both code and FS. Similar results:

Upload via esptool.py:
Successfully mounted LittleFS
spi_flash_read result :0
read0:1
read1:f7ff0ff0
read2:7474696c
read3:7366656c

Upload via OTA:
An Error has occurred while mounting LittleFS
spi_flash_read result :0
read0:20001
read1:f7ff0ff0
read2:7474696c
read3:7366656c

File:
Generated by HexEdit
00000000  01 00 00 00 f0 0f ff f7 6c 69 74 74 6c 65 66 73  ....ð.ÿ÷littlefs
earlephilhower commented 4 years ago

Changed title to underlying problem, @mike-s123, so that the changelist will be more meaningful. Thanks for the hex dump, it pinpointed this very quickly!

earlephilhower commented 4 years ago

@mike-s123 please try out the PR in #6891 and report back. Now the 1 byte change should only happen to applications, not filesystems.

mike-s123 commented 4 years ago

Works for me. Thanks, Earle.