-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Potential PR: over-the-air upgrade support #806
Comments
Sounds very interesting. I'd love to have this feature for NodeMCU and the |
Interesting. BTW, @raburton has an ESP bootloader with OTA support. I don't know if the advantage of having a single firmware outweighs the disadvantage of never supporting the ESP-01, which I expect will have several times the install base of the larger modules. End users will demand ESP-01 support. |
rBoot would satisfy many of the requirements stated in the PR, and those that it doesn't probably could be added without much effort. Certainly taking rBoot as a starting point would be a lot less effort than doing it from scratch, although I suspect from the description of the intended features and techniques the OP may have already looked at rBoot. I'd be very happy to help you integrate this and add any extra features you might need, either upstream or in a custom version, if you would like (I did this for Sming who now use it as their standard OTA mechanism). To answer the problems listed with the original sdk boot loader:
As for the plans for the new bootloader:
The drawbacks:
|
Given that a single standard minimal firmware image barely fits into an ESP-01, I don't see this as a real issue for Lua runtimes. There are two main usecases, IMO:
|
All my ESP-01 modules have 1 mbyte flash, so I should be able to squeeze two in there, I think. |
+1024, This will be awesome. as for the 512k modules like esp-01.
flash map changes procedure: ---> stage 1, download ota bootloader use nodemcu firmware from serverafter stage 1 flash map ---> reboot 1, the mini bootloader detects the ota bootloader exists, and copy it to right place.after reboot 1 flash map ---> stag 2, ota bootloader download nodemcu firmware from server.after stage 2 flash map ---> reboot 2, the mini bootloader detects the nodemcu firmware exists, and copy it to right place.after reboot 2 flash map ---> then nodemcu first run, format the file systemafter file system format flash map is this failsafe and can roll back to safe mode? |
@nodemcu rBoot is a fraction over 2k and sits in a single sector because it is a 'bare-metal' app, using only rom functions to interact with the device. The downside of this is no wifi, etc. If you want wifi you need to make a full normal app. This is going to weigh in at at least 200k, so you won't fit that on a 512k device alongside a copy of nodemcu. As for open source server side, you don't need anything special for the server - just a web server. No point reinventing the wheel when you just want to deliver a file across a network. |
I personally never missed that feature. I'm sure OTA-update support is handy in some more involved use cases (as DiUS' interest proves 😉) but for most users it would simply add a bit of convenience. I feel we have lots of more important issues we should spend our limited time with. |
@raburton so rBoot is like the sdk's FOTA but opensource. @marcelstoer, I think as a maker/hobbyist's toy, this add a bit of convenience. |
@nodemcu that's right, it was designed as an open source replacement for the sdk bootloader, with the same basic aims but with extra features and more flexibility. And of course being open source means you can extend it with whatever features you want, within reason. To remain as a bootloader it needs to be bare-metal and then load the real rom. If it's linked to the sdk libraries (as you'd need for network support) then it stops being a bootloader and just becomes a special purpose rom (at standard rom size), and incapable of loading the real target rom itself (it would need to swap things around and reboot to get the device to do the actual loading again of the target rom, a bit like in your example earlier). @marcelstoer I guess if you are mostly just flashing new lua scripts and usually keeping the core the same then serial flashing isn't a big deal, but for apps built with the sdk/Sming/etc. where the whole rom is reflashed the convenience of flashing ota in a couple of seconds vs getting back into the rom loader and serial flashing in a couple of minutes is a big improvement. However when you actually deploy something ota is much more important, especially if you were to deploy something on a large scale or commercially. I think that adding rBoot to nodemcu in it's simplest use case (like the original suggestion, using a pair of 1mb images on the flash from a single linked rom) would be trivial. If I get a chance I'll have a look at it this evening, but I'm not really that familiar with nodemcu use or internals so there will be a bit of a learning curve before I can get started. |
The firmware is just a standard SDK-based application. |
Definitely, but is NodeMCU ready for that? I don't want to hijack this conversation but @jmattsson can probably better assess this question than myself. My point is one of priority. I feel that NodeMCU has ways to go until "large scale" or "commercial" become relevant. I suggest we look into OTA once we get there, or shortly before that, rather than now. It's not just the ESP8266 which runs with constrained resources...it's the same for the NodeMCU team. |
Hard to imagine it would get to that point without something as basic as OTA support.
I'm not part of the nodemcu team and wouldn't be doing something else for the project instead. I personally have no interest in nodemcu, I just offered to help with this feature because someone pulled me into the conversation. |
But the build system isn't very friendly, so it's taken some figuring out how to get my bits compiled. Also, I really have no idea what to do with it now I have it up and running. I have a couple of nodemcu v0.9 boards which I bought for the handy hardware. When I got them I did briefly try to play with them before reflashing them, but got literally nowhere and quickly gave up. So now I need to try to figure out what I'm supposed to do with them in order to see how far I've actually got! |
Ok, progress was slower than expected but I have nodemcu firmware building for use with rBoot. My nodemcu board now has two copies of the nodemcu firmware on it, and you can query which of the two you are running and switch between them. Now I just need to add the actual ota code and we should have a working prototype. |
Added the ota code and it works. I can now ota update and switch between two different versions of nodemcu firmware. There is no error checking or feedback, it's a bit cobbled together at the moment, but it proves the point. |
Thanks! Sorry if I missed that in the earlier comments. I didn't realize you offered to actually implement this for us but I since found your #806 (comment). |
It sounds like people would prefer to go with an rBoot based OTA solution, and would really like to be able to do upgrades on sub-2meg chips as well. @raburton thank you for your work on this! Please feel free to glance at what we're using over in the DiUS OTA branch. It's fully functional and feature complete^ at this point. Actual firmware fetching is left up to the Lua code in our case. ^) For our needs. Though we might add a GPIO check to force switch at boot time. |
It sounds like people would prefer to go with an rBoot based OTA solution, and would really like to be able to do upgrades on sub-2meg chips as well. From the post I don't see any preferences. |
Yes. With rBoot you might even have more than two, I believe.
With the approach we've taken at DiUS, no, we use the same linker file for both. According to Richard's comment above, rBoot is capable of that too. In our case, we use the same linker file for regular NodeMCU builds as well as OTA-enabled builds.
The images have to start at a known offset on a megabyte boundary, in order for Cache_Read_Enable() to be able to map it correctly.
Yes. If you're overwriting your "good" image, you'll always risk this. That is why we picked the approach of using the SPI flash mapping to switch between images. No over-writing needed.
Yes, but at the cost of not having a fallback/rollback option.
This advantage we already get with either the DiUS OTA or rBoot (depending on its use). |
oops, it's right up there. that's good.
so a 2M minimal. how the file system mapped for the slot 0?
even after consistency check? if it refers to spi flash copy error, we can try many times. |
The file system doesn't go through the mapped SPI, but uses the raw flash API instead. As for the location, for a shared filesystem (same filesystem regardless of image 0 or 1 booted) you can set SPIFFS_FIXED_LOCATION to e.g. 0x200000 to have the filesystem at 2meg+. I'm working on support for having a per-image filesystem, where each image would have its own embedded filesystem.
I wasn't thinking so much about flash copy errors, but rather logical errors such as the new image not managing to connect over WiFi or fails talking to the upgrade server for some other reason. This is why we're so keen on the roll-back support - unless the new image actively tells the OTA subsystem that everything is A-OK, it will automatically revert back to a known-good firmware. |
@jmattsson Sorry, I didn't realise you'd already done all this, your description sounds very much like a plan of what you intended to do rather than having already done it. I thought I was offering a base that might give you a big head start but now it looks more like I've just hijacked your thread. @nodemcu I agree with @jmattsson there is really no safe way to be updating the running rom, the only safe way is a two rom system. In Sming this makes pretty much makes 512k flash support impossible, but nodemcu is a much larger rom than the average sming one so it definitely is, at 440k+ one copy barely fits on there, by the time you've allowed some space for a filesystem, 2 sectors for the bootloader and 4 for the sdk config. As a result fitting 2 on a 1mb flash will be just as tight, but it is just about doable. My suggestion would be implement the feature for devices 2mb or larger, because it's a lot simpler for the user and for the build system, but you do have the option to try to squeeze in support for 1mb flash (512k will never work though). To answer a few other random points/questions raised:
|
@raburton No need to apologise! The reason I worded this the way I did was that I'm not sure whether the DiUS OTA solution is the right one for NodeMCU overall, and wanted to see what people thought. It's quite possible that an rBoot solution is a better fit, and besides, it's always nice to have a bit of choice! Now, what we actually tend to do here at work is a 4-stage chain-load: ROM-> OTA boot loader -> DiUS sensor-sampler + loader -> NodeMCU Module docs for the DiUS OTA upgrade stuff are now available for those wishing to have a peek. The module is completely agnostic in terms of actually downloading the firmware (we have yet to agree on the best protocol & security to use). |
Hello, will this OTA method be eventually merged? Is there anything preventing that? Assuming that transfer to the spiffs is already covered somehow, would there be any issues with reading from the spiffs and flashing with this method? |
I'm honestly not sure whether this will be merged. Currently this is competing with the rBoot implementation, and before we go either way (or try to merge those two approaches) I need to understand how we would support OTA on the ESP32, and that's quite up in the air due to lack of hardware (and the substantial changes from the ESP31B engineering samples and the eventual ESP32 design). And no, there should be no issues using a file on SPIFFS as the source. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
So over at DiUS we're currently working on getting some over-the-air upgrade support into our NodeMCU. It's something that could be contributed back upstream if there's a real interest in it (and thus get it tested even more), so I'm wanting to gauge said interest. Before you get all excited, let me tell you the trade-offs that come with it.
First of all, we're not basing it around the official SDK's FOTA support. After researching it, we decided against using it because:
Because of this, we have decided to implement something which:
Specifically, our approach is not compatible/interchangeable with the SDK's FOTA, since:
However, the major drawbacks are:
I think that just about covers it. If there's a real interest I'll probably have to spend a chunk of the xmas break to curate it for upstream, so I'll only do that if it's really wanted.
*) This actually does depend on flash size, but that is not immediately obvious when you first start working with it.
The text was updated successfully, but these errors were encountered: