eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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:
MREADME.md | 18+++++++++++++-----
Mexamples/Cargo.lock | 401++-----------------------------------------------------------------------------
Mexamples/src/main.rs | 4++--
Mpartition-reader/src/main.rs | 4++++
Msimple-ota-server/firmware.bin | 0
Msrc/helpers.rs | 8+++-----
Msrc/lib.rs | 135++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/paddr.rs | 10+++++-----
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); } }