-
Notifications
You must be signed in to change notification settings - Fork 6
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
Add an example #5
base: main
Are you sure you want to change the base?
Conversation
Hi Linus I have a working HTTP OTA update that would make a good example, do you think it would be worthwhile to add it? Additionally, I have built an extension that performs a checksum of the update using ShA256. I have called this |
@@ -1,5 +1,6 @@ | |||
[build] | |||
# Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) | |||
# you may need to change the toolchain in `rust-toolc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is rust-toolc
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meant to be rust toolchain, xtensa chips need a custom toolchain afaik
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like an unfinished sentence then?
/.embuild | ||
/.devcontainer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You ignore the devcontainer folder here. But this PR also commits devcontainer definitions. I think you might want to remove the devcontainer files from this PR and keep it ignored?
Thank you for wanting to contribute! I have not read the entire PR yet. I left some comments on some things I think might have been commited by mistake as a first iteration. Will read more of it soon!
Having both signature verification (chip will only trust firmware signed by trusted parties) and integrity verification is something I really want in general. I have not yet coded this up for myself. And I have not decided if it belongs in this crate or outside. If it's put inside the crate then it becomes very opinionated as to what checksum algorithm and/or signature method it uses. But yeah, sha256 is universally a pretty solid choice, so it might be good! As long as we keep it behind an opt-in feature flag and the dependency it pulls in is sane and fairly small. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really lovely that you want to contribute! This crate deserves some more love!
Build: | ||
``` | ||
RUSTFLAGS="-C strip=symbols -C debuginfo=0" cargo build --example beta --release | ||
espflash save-image --chip <mcu_target> ./target/<mcu_target>/release/examples/beta ./beta.bin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR commits the beta.bin
file. I'm guessing that's a mistake, since these instructions build it? I don't think we should carry around built binaries in the repository.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will amend
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
beta.bin
is still part of this PR
|
||
Build: | ||
``` | ||
RUSTFLAGS="-C strip=symbols -C debuginfo=0" cargo build --example beta --release |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the stripping etc really need to be done here? It significantly complicates the example instructions. Is it required to fit on some specific type of chip? Otherwise I think simple instructions is more valuable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't need to happen, but it is an important aspect of OTA updates in my experience. We should mention it in the docs if not as part of the example, but it does greatly speed up the flashing.
|
||
## ota_from_flash | ||
|
||
The app contains the update in it's flash memory at compile time. The `beta.bin` image in the ESP32 app image format must be available at compile time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/it's/its/
|
||
## partitions_factory.csv | ||
|
||
The default partition table shipped with the ESP32. _Not suitable for OTA._ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this partition table included, since it's not used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I included it as a reference. Dodgy things might happen if a user doesn't re-write their original partition table.
For example, if you flash OTA alpha and OTA beta into partition slot ota1 and ota2 respectively. In this case, OTA alpha loads, writes OTA beta into the ota2 slot and selects that as the boot partition.
When a user wants to flash a non-ota app into what they expect to be the factory partition, the ota2 slot could still be selected as the boot partition, and the factory partition never opens :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's the responsibility of this repository to track the default partition table. If there are potential caveats (which are currently not even mentioned) I think it's far better to describe how to get out of the bad situation, and link to an online resource with the default partition table. Then we don't have to maintain it here
for app_chunk in NEW_APP.chunks(4096) { | ||
if let Err(err) = ota.write(app_chunk) { | ||
error!("Failed to write chunk"); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will just exit the for
loop and go directly to ota.finalize()
. Here we know the update failed already, and I don't think it's the best course of action to try and finalize the update. I think it's better in general (and teach the readers) to exit with an error here. Only run the finalize code if all write calls succeeded.
match ota.finalize() { | ||
Err(x) => { | ||
error!("Failed to validate image."); | ||
() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning unit is automatically implied when you don't return anything else. I believe this is superfluous here.
Hmm.. I thought about this again. How is it implemented? I don't want this crate to be locked to a specific format in how the images are transferred to the chip, neither be biased on the transport method. |
I agree that it is tough to be opionated regarding checksum algorithm. The ESP32 has CRC hardware support built in, for example. I think it would be a good idea to create a trait as the public interface, that we implement for SHA256 as a start, and allow future contributors to extend as desired.
My implementation is an extension of This is not locked into the specific format or transport method, but does require the user to also transfer the expected checksum over a side channel. |
@@ -1,5 +1,6 @@ | |||
[build] | |||
# Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) | |||
# you may need to change the toolchain in `rust-toolc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like an unfinished sentence then?
@@ -0,0 +1,66 @@ | |||
ARG VARIANT=bookworm-slim |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove these files
Build: | ||
``` | ||
RUSTFLAGS="-C strip=symbols -C debuginfo=0" cargo build --example beta --release | ||
espflash save-image --chip <mcu_target> ./target/<mcu_target>/release/examples/beta ./beta.bin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
beta.bin
is still part of this PR
|
||
## partitions_factory.csv | ||
|
||
The default partition table shipped with the ESP32. _Not suitable for OTA._ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's the responsibility of this repository to track the default partition table. If there are potential caveats (which are currently not even mentioned) I think it's far better to describe how to get out of the bad situation, and link to an online resource with the default partition table. Then we don't have to maintain it here
Add an example that updates an OTA enabled app using another app encoded in the flash memory.