-
Notifications
You must be signed in to change notification settings - Fork 13.3k
OTA which survives power failure #905
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
Comments
It's certainly possible to pass bootloader arguments via flash. This will require allocating an additional sector for eboot_command (like it is done in other bootloaders). |
Couldn't we have (optional) skip of updating the bootloader sector? |
Sure, such option may be implemented in Updater class. |
I could give this a try. Just not sure how to allocate the extra sector though. Never touched base with the linker before... Have to explore a bit first. |
The tricky part is to allocate this sector when users asks for it, so that flash space is not wasted by default. This could be an additional option in Tools menu or something like that. |
Maybe optionally using the last 128 bytes in the EEPROM sector |
I'm thinking of something else... since there are sectors at particular locations that are used by the SDK to store settings and such, maybe we can use those? They are a full 4K blocks but data in them is usually not more than 128B, so using the end of one of them can maybe give you the space for storing that data and not mess with EEPROM or the linkers. |
I'm a big fan of updates that survive power-failures (in as much as they don't render the device unusable). Aesthetically I like the idea of stealing a 4k page at the start of flash - so eboot and its config are all kept together. On a module with 4M this is no real issue, but I realise that this is more of a concern in smaller ones so it does really need to be optional. Does anyone have any thoughts/ideas on a suitable flash location? Because reducing SPIFFS_END resulted in a page that was overwritten, I'm wondering if shifting the start of SPIFFS is more reliable. As a side note I'm looking at allocating a full 4k with a view to storing general update config there as well, particularly a key for firmware signing/encryption. |
I think adding an extra 4k sector between eboot and the application is the best option. |
A non-optional one, or an optional one?
It's only marginally more complex to have it variable, but if it's
auto-detected more things may need to change - I'm not clear who/what makes
assumptions about where things are
I've got code which doesn't steal a 4k at the start, but stores the address
in the firmware image itself meaning you can put the block anywhere.I was
thinking adding an option to overwrite the bootloader would be included
(defaulting to off on the basis that its safer to not update the bootloader
to protect against power loss)
…On Thu, Dec 22, 2016 at 1:56 PM, Ivan Grokhotkov ***@***.***> wrote:
I think adding an extra 4k sector between eboot and the application is the
best option.
SDK 2.0 requires an extra sector reserved for RF calibration data, so
there will be some shifting things around anyway.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#905 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN_A4Nr7HrEycf_Y-CiQsq7_XdoWWmWks5rKcq5gaJpZM4GQ-lX>
.
|
Non-optional is fine. I'd say 4k matters only on 512k devices, but these are not very useful for OTA anyway. So this sector can be added to the LD scripts of all flash sizes from 1M and above, by defining some symbols like OTA_info_start and OTA_info_end. For 512k these to symbols can point to the same address, and the Updater figure out that the size of OTA info are is zero, hence RTC memory should be used instead (if anyone tries to use OTA on 512k, that is). |
Sounds good. That's the way the current logic works if you turn the flash
storage off, so I'll leave it doing that.
Will tidy up a few things and send it through ☺
If there's no objection I'll also leave in the ability to locate it
elsewhere, but default to just after eboot.
J,
…On 22/12/2016 2:44 pm, "Ivan Grokhotkov" ***@***.***> wrote:
Non-optional is fine. I'd say 4k matters only on 512k devices, but these
are not very useful for OTA anyway. So this sector can be added to the LD
scripts of all flash sizes from 1M and above, by defining some symbols like
OTA_info_start and OTA_info_end. For 512k these to symbols can point to the
same address, and the Updater figure out that the size of OTA info are is
zero, hence RTC memory should be used instead (if anyone tries to use OTA
on 512k, that is).
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#905 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN_A6KwswwASNXHCD1Sq-Ec64r0ubyeks5rKdYEgaJpZM4GQ-lX>
.
|
In (finally!) getting to tidying this up I've re-encountered the thing that originally led me to putting the page-of-settings somewhere other than the start of flash (by eboot). It also has implications for write-protecting (or, more accurately, not over-writing) eboot itself. Personally I don't mind overly, I do all my updating through a PHP-based website (uploads straight out of the IDE) which can do any manner of pre-processing before md5 comparisons - but it means that people couldn't do a simple md5sum on the binary as in the example PHP script. I suggest we start with putting the page at the start of SPIFFS and leave everything else as it is to minimise the impact on people who rely on the current MD5 behaviour. |
I see, that makes sense. Moving start of SPIFFS would probably be a headache, but reducing sketch size by 1 sector to make room for this config sector is probably okay. There's going to be a conflict with the changes I did in the 2.0 SDK branch, as there we need another extra sector for PHY calibration data, so I have done something similar there. Maybe it's going to be easier if I actually finish that PR and merge it, and then you can allocate another sector based on my changes. |
I've not widely tested SPIFFS, but there didn't seem too much problem just
adjusting the linker script to have a different SPIFFS start address (aside
from it needing to be 2 pages adjustment as that's the block size).
There were a couple of references in the rest of the code where it was
assumed that sketch-space-end == SPIFFS start, but easy to change.
If there's more page juggling pending that would be useful to get.
…On 18/01/2017 8:34 pm, "Ivan Grokhotkov" ***@***.***> wrote:
I see, that makes sense. Moving start of SPIFFS would probably be a
headache, but reducing sketch size by 1 sector to make room for this config
sector is probably okay.
There's going to be a conflict with the changes I did in the 2.0 SDK
branch, as there we need another extra sector for PHY calibration data, so
I have done something similar there. Maybe it's going to be easier if I
actually finish that PR and merge it, and then you can allocate another
sector based on my changes.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#905 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN_A0c9f7Pem8uYvDhb955uMaTZCHohks5rTcB0gaJpZM4GQ-lX>
.
|
Unfortunately, if we move SPIFFS we also need to adjust boards.txt file as it contains SPIFFS start addresses which are used by FS upload plugin. So that's the two places to make adjustments. |
I'd agree with that - a single point is best. |
Is it a terrible idea to move the SPIFFS declarations out of the .ld files entirely? |
Yes, we can add a bunch of But this would, for example, break https://github.com/plerup/makeEspArduino which is something I personally use for all my ESP8266-based projects, so clearly this option isn't something I'll agree upon easily, unless some reasonable workaround is presented (like throwing some Edit: apparently I haven't pulled latest makeEspArduino changes in a while — seems like build variable parsing is now implemented there. |
Sure is :) Everything is parsed from boards.txt etc |
That was the sort of thing I was wondering about breaking. If current
versions can already cope then that's at least one thing off the list.
I'd be keen to centralise the info in one place (boards.txt seems sensible)
and to eliminate some of the implicitness that exists in a couple of places
- such as Updater.cpp assuming the sketch-area ends at the start of the
SPIFFS area - using explicit boundary variables instead.
…On Fri, Jan 20, 2017 at 2:49 AM, Peter Lerup ***@***.***> wrote:
Sure is :)
Everything is parsed from boards.txt etc
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#905 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN_A9_tTf7ssAJVjJYZoObM8mnaJZb4ks5rT2nlgaJpZM4GQ-lX>
.
|
Okay @davisonja, if you can take a shot at this that would be awesome. I will then rebase my changes which allocate an extra sector for PHY data (needed for 2.0 SDK support) on top of your work. Thanks. |
I've actually gone back to these, currently bringing my branch into line
with master.
The problem is actually solved, just needs a tweak to the ld files (or
generation thereof)
…On Wed, 11 Sep 2019, 08:47 Robin Richtsfeld, ***@***.***> wrote:
Couldn't the data structure "eboot_command" be stored in flash instead and
not be reset until ACTION_COPY_RAW operation has been successfully
completed?
It has scope to increase functionality, the next two priority items to me
are allowing update from SPIFFS (so updates aren't limited to half program
space) and signed updates (which I think has been done).
These commits look like they would have solved these issues. But they are
dated 2015?
Can someone please tell me, which of these have actually been solved?
26eede8
<26eede8>,
d5b578b
<d5b578b>,
6f2069d
<6f2069d>,
d8acfff
<d8acfff>
(#5873 <#5873>)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#905?email_source=notifications&email_token=AABX6A5YNVXEHPK2VQAYQWTQJABWHA5CNFSM4BSD5FL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6MN5CY#issuecomment-530112139>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABX6A3L7BQVPGZNCN3EKYDQJABWHANCNFSM4BSD5FLQ>
.
|
Now on a laptop rather than a phone... @Androbin those commits look like the original ones that had update instructions being stored in the (volatile) RTC memory. I have a (now outdated) fork that happily stores the update instructions in a flash page, which thus survives power loss, and will just restart on each power-up until the process is complete. It's a fairly simple step from there to storing the new image somewhere that's outside the executable area. The only incomplete part of this solution was reserving the page, which is equally easy, but involved editing all the ld files. The path to doing that was ultimately deemed (back in the day) to be generating the ld files with a script, so my next step is to update that script to include the store-update-details-in-flash page. |
This issue was probably originally about updating the sketch. But it is equally applicable to the FS. So I've submitted a PR to help with that. |
If the FS needs a chip reset we can easily build that in, but it would still have the "half the potential size" limitation if it had to be downloaded while the system is running... |
I'm not sure where the right place to ask this is, so I'm going to note it here. I've been looking at ci failures for #6538 and thus organising the local builds on my dev machine - |
I've also had issues with Arduino IDE or plugins thereof being unable to locate the esptool binary. |
For those following this, and the ones who have comments inflicted on them, I picked up one of the "d1 mini pro" boards with 16MB flash. The default mode of this has a sizable |
Actually unrelated I now believe 🤦♂ Does anyone reading this have an opinion about allowing the OTA updates to store the update in, for those flash-configs that have it, the 'empty' section? I'm not sure whether the empty is intended for code to use. A side-effect of the way I've added the OTA flash parameter block to the |
@davisonja the area meant for ota is from after the current sketch up to before the FS. That area should be usable both for receiving a new sketch or for receiving a new FS image. An ota image received is supposed to get written in the high part of that empty space. There are no specific areas reserved in that empty area for other things. |
Now tested, slightly refined and un-draft'd #6538 is good to go. It's got the main things I originally wanted to get done back in 2017, so is complete from that perspective. There had been other discussions about additional potential functionality which I'm happy to add. Beyond that, what's next that needs fixed? Life's settled here, so it won't take years 😉 |
What are them ?
|
There's been interest in rboot inspired features, such as multiple images to boot in the past. I've also wondered about the value in storing ota info in an fs, as an alternative to the dedicated flash area. I've not been through littlefs properly to see how straightforward that is - I had a look at spiffs back in the day. These are simple things that could be achieved without expanding eboots size greatly. If you've got more flash to use there's other options that would involve making it bigger. |
LittleFS API is I am not familiar with rboot. Does it require that all images are stored below the first 1MB, or does rboot (re)flashes the chosen image when is it stored beyond the first 1MB ? |
I was thinking custom, read only support in eboot, rather than pulling in chunks of the main code base. Usually the complexity in filesystems is primarily the allocation, so writing. From the rboot page, though I've not looked at how applicable their strategy is here:
|
Then we could have one-step OTAs: |
Yup, assuming the remapping has no side effects that are problematic - I'm
on my phone so haven't read too far 😊
With some thought it's often possible to have auto fall back - if the
booted image gets reset by the watchdog too often, then boot into another
image, sort of thing.
…On Thu, 3 Oct 2019, 23:26 david gauchard, ***@***.***> wrote:
Then we could have one-step OTAs:
Flash once the other 1MB chunk, and on boot select the most recent one.
(one step flashing, not two-steps like we currently do)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#905?email_source=notifications&email_token=AABX6A4RCSVZJ5VEGQRF2KTQMXCFLA5CNFSM4BSD5FL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAHXV2A#issuecomment-537885416>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABX6AZNH63KG7BIE2EBYODQMXCFLANCNFSM4BSD5FLQ>
.
|
Correct about fallback and 1-step ota. The downside is that it requires reserving ghe two "slots" in flash, so you can't take advantage of a contiguous empty space area, e. g. for flashing a fs image. |
Default current flash mapping is to use (size)MB-2MB for FS at the end of flash addressing range, |
@davisonja said:
The idea was floated at some point to add support for compressed images, i.e.: receive an image that is compressed. The following possibilities for implementation have shown up:
Does this sound interesting enough to you to implement? |
That sounds like fun, @devyte :) I'll see what sort of sizes miniz turns into. Do we lodge new issues to centre and discussion around, or does that exist elsewhere? |
New issue please. |
MiniZ inflator alone takes 0x14b2 = 5298 bytes pf code when built with I just patched in a naive version into the bootloader and updated the makefile to
|
That's a more comprehensive assessment. I commented out the compressor code and built it to get an absolute upper bound, which was about 15k (with eboot, but no optimisations). It seemed like a viable prospect even at that size. |
For eboot, the makefile needs ti go from Then, the problem is that minigz has compress and decompress in one file and the linker will include the entire file even if compression is unused ( Granted, I did not test the resulting ELF, just looked at sizes. The eboot.c might have some code that's busted in a way to require no optimization to work. |
Maybe I'm missing something but I looks to me like if we have a power failure during the OTA update in eboot.c (ACTION_COPY_RAW) we end up with a non functional system.
Couldn't the data structure "eboot_command" be stored in flash instead and not be reset until ACTION_COPY_RAW operation has been successfully completed?
BR
/Peter
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: