-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
E][Updater.cpp:155] begin(): too large 1183629312 > 1310720 -- halts ESP32 #18
Comments
hey Christopher, It sounds like Obviously tarGzGetError() is useless after a system halt, so re-enabling the logging could help identify a possible error during decompression, could be a consequence of a nearly full or damaged SPIFFS partition, or a bug depending on the version of the library you're using. I'll need to know what version of the library produced this error though, there's a possibility it will behave differently with the latests release (0.3.0) or with the master branch (0.3.1). The gzUpdater example sketch was recently updated, it was tested both on M5Stack and LoLinD32 pro successfully. Can you try and see if this one works with the master branch ? This is the expected output: |
I think I understand the issue, but do not know how to solve. I decided to show what files exist and I found part of my firmware still on the file system. Fine, put in a delete in case there was an error to cleanup. But now:
My code:
So, that file list just doesn't add up to 494,219 bytes. I don't see any other files. My concern now is there are some temporary files that are hidden or the decompression somehow mangled the SPIFFS file system. I am hesitant to touch the SPIFFS partition now, because I need to understand where the space has gone. So I can't run the example at this time. This is a standard 4MB ESP32 Dev kit, with a standard SPIFFS partition definition. Can you provide any insight as to temp files created during the decompression? |
With gzUpdater there is no temporary file, the decompressed bytes are passed directly to Update::writeStream and written on the OTA partition. SPIFFS has a few annoying fragmentation bugs though, most of them are triggered by writing incomplete files, overwriting or deleting, all solved by formatting.
Here's how to use tarGzExpander without the intermediate file:
This won't prevent files from being overwritten but may avoid being close to a nearly full partition, so it's more a mitigation than a solution. LittleFS has a better error detection and is much more resilitent, I wish this was the official partition scheme instead of SPIFFS :-) |
First, thanks for the attention to this issue. I do download the firmware to a fixed file name, process then delete the file. Rinse and repeat. If SPIFFS has some fundamental issue writing to a filename that is constant, then deleting and potentially ending up with internal fragmentation, that's a show stopper for me because I preload the certs / keys for secure connections in the SPIFFS partition. The downloaded firmware sits along side that content (about 60k). If at some point the available space < gzipped firmware, I cannot simply reformat. I'll have to look into this deeper, perhaps multiple SPIFFS partitions, one for static data and one for downloads that can be reformatted. Since this intersects with your work, I'll inform where I end up with this so others can understand at least where I land on this. Many thanks again |
if that may be of interest, I'm currently researching how to do http-stream => gzuncompress => update-partition with no intermediary file at all, but the simple example sketch is already eating 67% of program storage space so it's not really lightweight, and I still have to make it work ^^ |
Dude. That would be killer! |
Ive added a gzStreamUpdater example to the latest release but it makes a huge sketch, I wonder how this will affect projects with existing WiFiClient and http objects, maybe not that much. |
Wow -- awesome. Let me give it a shot! |
So here are the results of the test of this new capability with my rig. As per your sketch, once my http connection is established, I just injected the gzStreamUpdater call ahead of what I normally do:
Running with -DCORE_DEBUG_LEVEL=5, there's a per-character log line emitted from line 431. I strongly suggest you remove this, else it's a per-character read log line and life is too short:
In order to really see what's going on, I commented that out. Much better log output:
So a few observations:
which means it's not reading the entire file. Once the fail happens, it falls through to my original loop which is able to read an additional 4 bytes from the stream, and that would be the complete read. 2). I see these occasionally during the download:
3). The number of read errors does NOT correspond to lost bytes. 4). Multiple runs always end with the same 4 bytes not read from the stream. If this works, it's a FAR superior method of pulling firmware, so I'm excited to get through this. Finally, my firmware is just that -- there is no 4-byte header for size or anything abnormal about staging this on the server. Just a gzip --keep --best --force on an ubuntu server. |
thanks for this detailed report I'm not sure where those 4 missing bytes come from, and I can't reproduce this error so I'll assume it's a consequence of the previous Because the The message Since I'm in the middle of researching |
Some good news! This consistently works:
So, aside from killing the log_v read 1 byte (I beg you), just add a one-time retry. Also, if this routine does ever error out, I'd abort the attempt. Now when it fails, I only see the initial fail fingerprint in the log:
It's unclear why there is a read fail and the available() is zero, but next attempt it always succeeds. I've put a delay(1) in that routine before and tested, but it was exactly the same behavior. What might make sense is to give it 5 attempts with a delay(1) after the fail, then flag the entire process should bail if it can't read. Again, it always succeeds the second attempt for me. Also please make the first:
a log_d. So yay! This should work, and I believe it's a superior approach to firmware updates on the esp32 (gzipped fw, download to a 4k buffer, decomp to the ota partition). Awesome! |
ooh thanks for finding that out, I didn't know it was even possible to recover from a single read error ;) I've added the changes you suggested to my current workspace and will commit them soon with many other changes : I'm namespacing TAR and GZ underlying libraries and moving from functions to object+methods. Those are breaking changes and I'll probably have to increment the library major version number and add the alpha flag, update documentation+examples, and also add an extra development iteration for ESP8266 support before I publish the next release, so it'll stay on a separate branch until then. |
hey @scubachristopher I want to close this thread as it's getting very long, can you confirm the original issue is now fixed for you? The new release of esp32-targz includes your suggested fix. |
heya @tobozo:
Thanks (and will close) |
thanks! Actually tarGzStreamUpdater is only useful when both spiffs and app partitions need to be flashed. It's slightly faster since it saves one extra HTTP connection, maybe more reliable as some situations won't let the ESP make two HTTPS connections in a row. closing this issue as solved |
Hi,
What's interesting is I've had no issues with this code for some time. Download was successful, file size was 673935. Once I download the new firmware to SPIFFS, I reboot the ESP and immediate try to flash. When I call:
gzUpdater(SPIFFS, "/dlfirmware.bin.gz");
I get:
[E][Updater.cpp:155] begin(): too large 1183629312 > 1310720
Fine. Something went wrong. But it literally halts the ESP. Am moving my wdt start above this code -- perhaps that will solve the halt but reproducing this might be difficult.
I am not familiar with how the update process works (begin, end), but is there a size check that can gracefully catch this scenario in gzUpdater?
Any perspective on this would be appreciated. Halting on FW update will brick the device, as I cannot remove the fw from SPIFFS until after gzUpdater returns, which it did not...
Am on 0.2.1. Upgrade?
The text was updated successfully, but these errors were encountered: