commit 58659923a359979856b07fca33bf2067598993b7
parent 06e1edd9495d6a540ef308281788cbab7118067d
Author: filipton <filipton12@gmail.com>
Date: Thu, 4 Jul 2024 19:37:53 +0200
feat: add set_target_ota_boot_partition function and partition.csv template
Diffstat:
5 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -13,4 +13,11 @@ name = "esp-hal-ota"
version = "0.1.0"
dependencies = [
"embedded-storage",
+ "log",
]
+
+[[package]]
+name = "log"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
diff --git a/Cargo.toml b/Cargo.toml
@@ -7,3 +7,4 @@ edition = "2021"
[dependencies]
embedded-storage = "0.3.1"
+log = "0.4.22"
diff --git a/partitions.csv.template b/partitions.csv.template
@@ -0,0 +1,6 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x4000,
+otadata, data, ota, 0xd000, 0x2000,
+phy_init, data, phy, 0xf000, 0x1000,
+ota_0, app, ota_0, 0x10000, 0x100000,
+ota_1, app, ota_1, 0x110000, 0x100000,
diff --git a/src/lib.rs b/src/lib.rs
@@ -6,7 +6,8 @@ pub mod crc32;
pub mod helpers;
pub mod paddr;
-// TOOD: make macros for generating this from partitions.csv, delete them from lib
+// 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 = 2;
pub const PARTITIONS: [core::ops::Range<u32>; PARTITIONS_COUNT] = [
(0x10000..0x10000 + 0x100000),
@@ -16,7 +17,7 @@ pub const PARTITIONS: [core::ops::Range<u32>; PARTITIONS_COUNT] = [
pub const OTADATA_OFFSET: u32 = 0xd000;
pub const OTADATA_SIZE: u32 = 0x2000;
-// I need to use generics, because after adding esp-storage dependency to
+// I need to use generics, because after adding esp-storage dependency to
// this project its not compiling LULE
pub struct Ota<S>
where
@@ -25,7 +26,50 @@ where
flash: S,
}
-impl<S> Ota<S> where S: ReadStorage + Storage {
+impl<S> Ota<S>
+where
+ S: ReadStorage + Storage,
+{
+ pub fn set_target_ota_boot_partition(&mut self, target: usize) {
+ let flash = &mut self.flash;
+ let mut bytes = [0; 32];
+
+ _ = flash.read(OTADATA_OFFSET, &mut bytes);
+ let crc_1 = u32::from_le_bytes(bytes[(32 - 4)..32].try_into().unwrap());
+ let seq_1 = helpers::seq_or_default(&bytes[..4], crc_1, 0);
+
+ _ = flash.read(OTADATA_OFFSET + (OTADATA_SIZE >> 1), &mut bytes);
+ let crc_2 = u32::from_le_bytes(bytes[(32 - 4)..32].try_into().unwrap());
+ let seq_2 = helpers::seq_or_default(&bytes[..4], crc_2, 0);
+
+ let mut target_seq = seq_1.max(seq_2);
+ while helpers::seq_to_part(target_seq) != target || target_seq == 0 {
+ target_seq += 1;
+ }
+
+ let target_crc = crc32::calc_crc32(&target_seq.to_le_bytes(), 0xFFFFFFFF);
+ if seq_1 > seq_2 {
+ let offset = OTADATA_OFFSET + (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());
+ }
+ }
+
+ pub fn get_currently_booted_partition() -> Option<usize> {
+ paddr::esp_get_current_running_partition()
+ }
+
+ /// BUG: this wont work if user has ota partitions not starting from ota0
+ /// or if user skips some ota partitions: ota0, ota2, ota3...
+ 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 dsa(&mut self) {
//self.flash.write(offset, bytes)
}
diff --git a/src/paddr.rs b/src/paddr.rs
@@ -2,15 +2,15 @@ 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;
+//const MMU_PAGE_64KB: u32 = 0x10000;
const DR_REG_MMU_TABLE: u32 = 0x600c5000;
const SOC_MMU_VALID_VAL_MASK: u32 = 0x3fff;
-pub fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
+fn mmu_ll_get_entry_id(_mmu_id: u32, vaddr: u32) -> u32 {
(vaddr & SOC_MMU_VADDR_MASK) >> 16
}
-pub fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
+fn mmu_ll_entry_id_to_paddr_base(_mmu_id: u32, entry_id: u32) -> u32 {
let ptr = (DR_REG_MMU_TABLE + entry_id * 4) as *const u32;
unsafe { ((*ptr) & SOC_MMU_VALID_VAL_MASK) << 16 }
}