commit 0f715179169652f3b8f73668af34f93129baeeec
parent 4cca1325aa850fd27db5d1e469e2775e0c567d7f
Author: filipton <filipton12@gmail.com>
Date: Fri, 5 Jul 2024 12:57:52 +0200
feat: read ota partitions straight from flash (no need for macros)
Diffstat:
8 files changed, 139 insertions(+), 441 deletions(-)
diff --git a/README.md b/README.md
@@ -16,10 +16,17 @@ socket
.expect("Cannot read firmware size!");
let flash_size = u32::from_le_bytes(ota_buff[..4].try_into().unwrap());
+
+socket
+ .read(&mut ota_buff[..4])
+ .await
+ .expect("Cannot read target crc!");
+let target_crc = u32::from_le_bytes(ota_buff[..4].try_into().unwrap());
log::info!("flash_size: {flash_size}");
+log::info!("target_crc: {target_crc}");
-let mut ota = Ota::new(FlashStorage::new()).with_next_partition_offset();
-ota.set_flash_size(flash_size);
+let mut ota = Ota::new(FlashStorage::new()).unwrap();
+ota.ota_begin(flash_size, target_crc);
let mut bytes_read = 0;
loop {
@@ -37,6 +44,7 @@ loop {
if res == Ok(true) {
_ = ota.ota_flush();
+ // Here just reboot or sth!
break;
}
}
@@ -47,11 +55,11 @@ loop {
```
## Todo
-- [ ] Fully working library
-- [ ] Partitions macro (to generate PARTITIONS const at compile time)
+- [x] Fully working library
+- [x] Simple example
+- [ ] Better errors
- [ ] Other esp32's (like esp32c3, esp32s2, etc..)
- [ ] Rollbacks
-- [x] Simple example
## Resources
- https://github.com/esp-rs/espflash (this led me to esp-idf-part)
diff --git a/examples/Cargo.lock b/examples/Cargo.lock
@@ -87,12 +87,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
[[package]]
-name = "base64"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-
-[[package]]
name = "basic-toml"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -120,47 +114,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
-name = "bitvec"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
-dependencies = [
- "funty",
- "radium",
- "tap",
- "wyz",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
-dependencies = [
- "generic-array 0.14.7",
-]
-
-[[package]]
-name = "bytemuck"
-version = "1.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e"
-dependencies = [
- "bytemuck_derive",
-]
-
-[[package]]
-name = "bytemuck_derive"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.68",
-]
-
-[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -186,15 +139,6 @@ dependencies = [
]
[[package]]
-name = "cpufeatures"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -210,68 +154,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
-name = "crypto-common"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
-dependencies = [
- "generic-array 0.14.7",
- "typenum",
-]
-
-[[package]]
-name = "csv"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
-dependencies = [
- "csv-core",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "csv-core"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "darling"
-version = "0.14.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
-dependencies = [
- "darling_core 0.14.4",
- "darling_macro 0.14.4",
-]
-
-[[package]]
name = "darling"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
dependencies = [
- "darling_core 0.20.9",
- "darling_macro 0.20.9",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.14.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
-dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim 0.10.0",
- "syn 1.0.109",
+ "darling_core",
+ "darling_macro",
]
[[package]]
@@ -284,56 +173,22 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
- "strsim 0.11.1",
+ "strsim",
"syn 2.0.68",
]
[[package]]
name = "darling_macro"
-version = "0.14.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
-dependencies = [
- "darling_core 0.14.4",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "darling_macro"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
- "darling_core 0.20.9",
+ "darling_core",
"quote",
"syn 2.0.68",
]
[[package]]
-name = "deku"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819b87cc7a05b3abe3fc38e59b3980a5fd3162f25a247116441a9171d3e84481"
-dependencies = [
- "bitvec",
- "deku_derive",
-]
-
-[[package]]
-name = "deku_derive"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e2ca12572239215a352a74ad7c776d7e8a914f8a23511c6cbedddd887e5009e"
-dependencies = [
- "darling 0.14.4",
- "proc-macro-crate 1.3.1",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
name = "delegate"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -345,16 +200,6 @@ dependencies = [
]
[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "crypto-common",
-]
-
-[[package]]
name = "document-features"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -389,7 +234,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad454accf80050e9cf7a51e994132ba0e56286b31f9317b68703897c328c59b5"
dependencies = [
- "darling 0.20.9",
+ "darling",
"proc-macro2",
"quote",
"syn 2.0.68",
@@ -627,7 +472,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"
dependencies = [
- "darling 0.20.9",
+ "darling",
"proc-macro2",
"quote",
"syn 2.0.68",
@@ -730,7 +575,6 @@ name = "esp-hal-ota"
version = "0.1.0"
dependencies = [
"embedded-storage",
- "espflash",
"log",
]
@@ -740,11 +584,11 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "788b535b8127a8f0d1f40a8d8e300e57a8c361c492d660dd08fe8e9a1b96ee3c"
dependencies = [
- "darling 0.20.9",
+ "darling",
"document-features",
"litrs",
"object",
- "proc-macro-crate 3.1.0",
+ "proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
@@ -752,24 +596,6 @@ dependencies = [
]
[[package]]
-name = "esp-idf-part"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59f50b6c32370067087b46087cd5333f2dfe678f0b01223fa70fde6f15449844"
-dependencies = [
- "csv",
- "deku",
- "heapless",
- "md5",
- "parse_int",
- "regex",
- "serde",
- "serde_plain",
- "strum 0.26.3",
- "thiserror",
-]
-
-[[package]]
name = "esp-metadata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -880,27 +706,6 @@ dependencies = [
]
[[package]]
-name = "espflash"
-version = "3.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ae94ed72994aee4c41142198ef915f9c35be9915f0b9c057c49b09bd1b4e099"
-dependencies = [
- "base64",
- "bytemuck",
- "esp-idf-part",
- "flate2",
- "libc",
- "log",
- "md-5",
- "miette",
- "serde",
- "sha2",
- "strum 0.26.3",
- "thiserror",
- "xmas-elf",
-]
-
-[[package]]
name = "flate2"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -926,12 +731,6 @@ dependencies = [
]
[[package]]
-name = "funty"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
-
-[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1064,7 +863,6 @@ checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
dependencies = [
"hash32",
"portable-atomic",
- "serde",
"stable_deref_trait",
]
@@ -1097,24 +895,12 @@ dependencies = [
]
[[package]]
-name = "itoa"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
-
-[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
-name = "libc"
-version = "0.2.155"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
-
-[[package]]
name = "libm"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1158,51 +944,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
[[package]]
-name = "md-5"
-version = "0.10.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
-dependencies = [
- "cfg-if",
- "digest",
-]
-
-[[package]]
-name = "md5"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
-
-[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
-name = "miette"
-version = "7.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1"
-dependencies = [
- "cfg-if",
- "miette-derive",
- "thiserror",
- "unicode-width",
-]
-
-[[package]]
-name = "miette-derive"
-version = "7.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.68",
-]
-
-[[package]]
name = "minijinja"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1279,21 +1026,6 @@ dependencies = [
]
[[package]]
-name = "once_cell"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
-
-[[package]]
-name = "parse_int"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d695b79916a2c08bcff7be7647ab60d1402885265005a6658ffe6d763553c5a"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1340,16 +1072,6 @@ dependencies = [
[[package]]
name = "proc-macro-crate"
-version = "1.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
-dependencies = [
- "once_cell",
- "toml_edit 0.19.15",
-]
-
-[[package]]
-name = "proc-macro-crate"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
@@ -1406,12 +1128,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
[[package]]
-name = "radium"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
-
-[[package]]
name = "ral-registers"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1509,12 +1225,6 @@ dependencies = [
]
[[package]]
-name = "ryu"
-version = "1.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
-
-[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1547,15 +1257,6 @@ dependencies = [
]
[[package]]
-name = "serde_plain"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50"
-dependencies = [
- "serde",
-]
-
-[[package]]
name = "serde_spanned"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1565,17 +1266,6 @@ dependencies = [
]
[[package]]
-name = "sha2"
-version = "0.10.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
name = "smoltcp"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1620,12 +1310,6 @@ dependencies = [
[[package]]
name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
-[[package]]
-name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
@@ -1694,12 +1378,6 @@ dependencies = [
]
[[package]]
-name = "tap"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
-
-[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1709,26 +1387,6 @@ dependencies = [
]
[[package]]
-name = "thiserror"
-version = "1.0.61"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.61"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.68",
-]
-
-[[package]]
name = "toml"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1765,17 +1423,6 @@ dependencies = [
[[package]]
name = "toml_edit"
-version = "0.19.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
-dependencies = [
- "indexmap",
- "toml_datetime",
- "winnow 0.5.40",
-]
-
-[[package]]
-name = "toml_edit"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
@@ -1821,12 +1468,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
-name = "unicode-width"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
-
-[[package]]
name = "usb-device"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1955,24 +1596,6 @@ dependencies = [
]
[[package]]
-name = "wyz"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
-dependencies = [
- "tap",
-]
-
-[[package]]
-name = "xmas-elf"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42c49817e78342f7f30a181573d82ff55b88a35f86ccaf07fc64b3008f56d1c6"
-dependencies = [
- "zero",
-]
-
-[[package]]
name = "xtensa-lx"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2002,14 +1625,8 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "082cdede098bbec9af15b0e74085e5f3d16f2923597de7aed7b8112003af2da7"
dependencies = [
- "darling 0.20.9",
+ "darling",
"proc-macro2",
"quote",
"syn 2.0.68",
]
-
-[[package]]
-name = "zero"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fe21bcc34ca7fe6dd56cc2cb1261ea59d6b93620215aefb5ea6032265527784"
diff --git a/examples/src/main.rs b/examples/src/main.rs
@@ -108,7 +108,7 @@ async fn main(spawner: Spawner) {
log::info!("flash_size: {flash_size}");
log::info!("target_crc: {target_crc}");
- let mut ota = Ota::new(FlashStorage::new());
+ let mut ota = Ota::new(FlashStorage::new()).expect("Cannot create ota");
ota.ota_begin(flash_size, target_crc);
let mut bytes_read = 0;
@@ -137,7 +137,7 @@ async fn main(spawner: Spawner) {
loop {
log::info!("bump");
- Timer::after_millis(1000).await;
+ Timer::after_millis(15000).await;
}
}
diff --git a/partition-reader/src/main.rs b/partition-reader/src/main.rs
@@ -3,6 +3,10 @@ const PARTITION_BYTES: &[u8] = include_bytes!("../part.bin");
fn main() {
let chunks = PARTITION_BYTES.chunks(32);
for chunk in chunks {
+ if chunk == &[0xFF; 32] {
+ break;
+ }
+
let magic = &chunk[0..2];
if magic != &[0xAA, 0x50] {
continue;
diff --git a/simple-ota-server/firmware.bin b/simple-ota-server/firmware.bin
Binary files differ.
diff --git a/src/helpers.rs b/src/helpers.rs
@@ -1,17 +1,15 @@
-use crate::{crc32, PARTITIONS_COUNT};
-
#[inline(always)]
/// Helper funcion!
/// Change seq to partition number
-pub const fn seq_to_part(seq: u32) -> usize {
- (seq as usize - 1) % PARTITIONS_COUNT
+pub const fn seq_to_part(seq: u32, partitions_count: usize) -> usize {
+ (seq as usize - 1) % partitions_count
}
#[inline(always)]
/// Helper funcion!
/// If crc of seq is correct it returns seq, otherwise default value is returned
pub fn seq_or_default(seq: &[u8], crc: u32, default: u32) -> u32 {
- let crc_calc = crc32::calc_crc32(&seq, 0xFFFFFFFF);
+ let crc_calc = crate::crc32::calc_crc32(&seq, 0xFFFFFFFF);
if crc == crc_calc {
return u32::from_le_bytes(seq.try_into().expect("Wrong size?"));
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -6,17 +6,9 @@ pub mod crc32;
pub mod helpers;
pub mod paddr;
-// TODO: make macros for generating this from partitions.csv, delete them from lib
-// Maybe just add it as args to Ota object?
-pub const PARTITIONS_COUNT: usize = 3;
-pub const PARTITIONS: [core::ops::Range<u32>; PARTITIONS_COUNT] = [
- (0x10000..0x10000 + 0x100000),
- (0x110000..0x110000 + 0x100000),
- (0x210000..0x210000 + 0x100000),
-];
-
-pub const OTADATA_OFFSET: u32 = 0xd000;
-pub const OTADATA_SIZE: u32 = 0x2000;
+const PART_OFFSET: u32 = 0x8000;
+const PART_SIZE: u32 = 0xc00;
+const FIRST_OTA_PART_SUBTYPE: u8 = 0x10;
#[derive(Clone)]
pub struct FlashProgress {
@@ -29,6 +21,15 @@ pub struct FlashProgress {
target_crc: u32,
}
+#[derive(Debug)]
+pub struct PartitionInfo {
+ ota_partitions: [(u32, u32); 16],
+ ota_partitions_count: usize,
+
+ otadata_offset: u32,
+ otadata_size: u32,
+}
+
// NOTE: I need to use generics, because after adding esp-storage dependency to
// this project its not compiling LULE
pub struct Ota<S>
@@ -36,7 +37,9 @@ where
S: ReadStorage + Storage,
{
flash: S,
+
progress: Option<FlashProgress>,
+ pinfo: PartitionInfo,
}
// TODO: add OtaError enum
@@ -45,17 +48,30 @@ impl<S> Ota<S>
where
S: ReadStorage + Storage,
{
- pub fn new(flash: S) -> Self {
- Ota {
- flash,
- progress: None,
+ pub fn new(mut flash: S) -> Result<Self, ()> {
+ if let Some(pinfo) = Self::read_partitions(&mut flash) {
+ log::info!("parts: {:?}", &pinfo);
+
+ return Ok(Ota {
+ flash,
+ progress: None,
+ pinfo,
+ });
}
+
+ Err(())
+ }
+
+ fn get_partitions(&self) -> &[(u32, u32)] {
+ &self.pinfo.ota_partitions[..self.pinfo.ota_partitions_count]
}
/// To begin ota update (need to provide flash size)
pub fn ota_begin(&mut self, size: u32, target_crc: u32) {
- let next_part = Self::get_next_ota_partition().expect("Add error handling here");
- let ota_offset = PARTITIONS[next_part].start;
+ let next_part = self
+ .get_next_ota_partition()
+ .expect("Add error handling here");
+ let ota_offset = self.get_partitions()[next_part].0;
self.progress = Some(FlashProgress {
last_crc: 0,
@@ -109,8 +125,8 @@ where
pub fn ota_flush(&mut self) -> Result<(), ()> {
let progress = self.progress.clone().ok_or_else(|| ())?; // add error like OtaNotStarted
if progress.target_crc != progress.last_crc {
- log::info!("[OTA] Calculated crc: {:?}", progress.last_crc);
- log::info!("[OTA] Target crc: {:?}", progress.target_crc);
+ log::warn!("[OTA] Calculated crc: {:?}", progress.last_crc);
+ log::warn!("[OTA] Target crc: {:?}", progress.target_crc);
log::error!("[OTA] Crc check failed! Cant finish ota update...");
return Err(()); // wrong crc err or sth like this
@@ -125,20 +141,25 @@ where
let (seq1, seq2) = self.get_ota_boot_sequences();
let mut target_seq = seq1.max(seq2);
- while helpers::seq_to_part(target_seq) != target || target_seq == 0 {
+ while helpers::seq_to_part(target_seq, self.pinfo.ota_partitions_count) != target
+ || target_seq == 0
+ {
target_seq += 1;
}
let flash = &mut self.flash;
let target_crc = crc32::calc_crc32(&target_seq.to_le_bytes(), 0xFFFFFFFF);
if seq1 > seq2 {
- let offset = OTADATA_OFFSET + (OTADATA_SIZE >> 1);
+ let offset = self.pinfo.otadata_offset + (self.pinfo.otadata_size >> 1);
_ = flash.write(offset, &target_seq.to_le_bytes());
_ = flash.write(offset + 32 - 4, &target_crc.to_le_bytes());
} else {
- _ = flash.write(OTADATA_OFFSET, &target_seq.to_le_bytes());
- _ = flash.write(OTADATA_OFFSET + 32 - 4, &target_crc.to_le_bytes());
+ _ = flash.write(self.pinfo.otadata_offset, &target_seq.to_le_bytes());
+ _ = flash.write(
+ self.pinfo.otadata_offset + 32 - 4,
+ &target_crc.to_le_bytes(),
+ );
}
}
@@ -148,13 +169,14 @@ where
pub fn get_ota_boot_sequences(&mut self) -> (u32, u32) {
let mut bytes = [0; 32];
- _ = self.flash.read(OTADATA_OFFSET, &mut bytes);
+ _ = self.flash.read(self.pinfo.otadata_offset, &mut bytes);
let crc1 = u32::from_le_bytes(bytes[(32 - 4)..32].try_into().unwrap());
let seq1 = helpers::seq_or_default(&bytes[..4], crc1, 0);
- _ = self
- .flash
- .read(OTADATA_OFFSET + (OTADATA_SIZE >> 1), &mut bytes);
+ _ = self.flash.read(
+ self.pinfo.otadata_offset + (self.pinfo.otadata_size >> 1),
+ &mut bytes,
+ );
let crc2 = u32::from_le_bytes(bytes[(32 - 4)..32].try_into().unwrap());
let seq2 = helpers::seq_or_default(&bytes[..4], crc2, 0);
@@ -162,8 +184,8 @@ where
}
/// Returns currently booted partition index
- pub fn get_currently_booted_partition() -> Option<usize> {
- paddr::esp_get_current_running_partition()
+ pub fn get_currently_booted_partition(&self) -> Option<usize> {
+ paddr::esp_get_current_running_partition(self.get_partitions())
}
/// BUG: this wont work if user has ota partitions not starting from ota0
@@ -172,8 +194,57 @@ where
/// NOTE: This isn't reading from ota_boot_sequences, maybe in the future
/// it will read from them to eliminate possibility of wrong PADDR result.
/// (ESP-IDF has if's for PADDR-chain so it can fail somehow)
- pub fn get_next_ota_partition() -> Option<usize> {
- let curr_part = paddr::esp_get_current_running_partition();
- curr_part.map(|next_part| (next_part + 1) % PARTITIONS_COUNT)
+ pub fn get_next_ota_partition(&self) -> Option<usize> {
+ let curr_part = paddr::esp_get_current_running_partition(self.get_partitions());
+ curr_part.map(|next_part| (next_part + 1) % self.pinfo.ota_partitions_count)
+ }
+
+ fn read_partitions(flash: &mut S) -> Option<PartitionInfo> {
+ let mut tmp_pinfo = PartitionInfo {
+ ota_partitions: [(0, 0); 16],
+ ota_partitions_count: 0,
+ otadata_size: 0,
+ otadata_offset: 0,
+ };
+
+ let mut bytes = [0xFF; 32];
+ let mut last_ota_part: i8 = -1;
+ for read_offset in (0..PART_SIZE).step_by(32) {
+ _ = flash.read(PART_OFFSET + read_offset, &mut bytes);
+ if &bytes == &[0xFF; 32] {
+ break;
+ }
+
+ let magic = &bytes[0..2];
+ if magic != &[0xAA, 0x50] {
+ continue;
+ }
+
+ let p_type = &bytes[2];
+ let p_subtype = &bytes[3];
+ let p_offset = u32::from_le_bytes(bytes[4..8].try_into().unwrap());
+ let p_size = u32::from_le_bytes(bytes[8..12].try_into().unwrap());
+ //let p_name = core::str::from_utf8(&bytes[12..28]).unwrap();
+ //let p_flags = u32::from_le_bytes(bytes[28..32].try_into().unwrap());
+ //log::info!("{magic:?} {p_type} {p_subtype} {p_offset} {p_size} {p_name} {p_flags}");
+
+ if *p_type == 0 && *p_subtype >= FIRST_OTA_PART_SUBTYPE {
+ let ota_part_idx = *p_subtype - FIRST_OTA_PART_SUBTYPE;
+ if ota_part_idx as i8 - last_ota_part != 1 {
+ log::error!("Wrong ota partitions order!");
+ return None;
+ }
+
+ last_ota_part = ota_part_idx as i8;
+ tmp_pinfo.ota_partitions[tmp_pinfo.ota_partitions_count] = (p_offset, p_size);
+ tmp_pinfo.ota_partitions_count += 1;
+ } else if *p_type == 1 && *p_subtype == 0 {
+ //otadata
+ tmp_pinfo.otadata_offset = p_offset;
+ tmp_pinfo.otadata_size = p_size;
+ }
+ }
+
+ Some(tmp_pinfo)
}
}
diff --git a/src/paddr.rs b/src/paddr.rs
@@ -1,5 +1,3 @@
-use crate::{PARTITIONS, PARTITIONS_COUNT};
-
// this is for esp32s3, TODO: implement for other esp32's
const SOC_MMU_VADDR_MASK: u32 = 0x1FFFFFF;
//const MMU_PAGE_64KB: u32 = 0x10000;
@@ -15,7 +13,7 @@ fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << 16 }
}
-pub fn esp_get_current_running_partition() -> Option<usize> {
+pub fn esp_get_current_running_partition(partitions: &[(u32, u32)]) -> Option<usize> {
let ptr = esp_get_current_running_partition as *const () as *const u32;
let entry_id = mmu_ll_get_entry_id(0, ptr as u32);
@@ -27,8 +25,10 @@ pub fn esp_get_current_running_partition() -> Option<usize> {
let paddr_base = mmu_ll_entry_id_to_paddr_base(0, entry_id);
let paddr = paddr_base | offset;
- for i in 0..PARTITIONS_COUNT {
- if PARTITIONS[i].contains(&paddr) {
+ for i in 0..partitions.len() {
+ let part = partitions[i];
+
+ if paddr >= part.0 && paddr < part.0 + part.1 {
return Some(i);
}
}