eculocate

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

commit 83ce1812642615252403701fdf8e6e06db487606
parent 0979e2137d25cfdb6a39d1abe884154d825dedea
Author: filipton <filipton12@gmail.com>
Date:   Sat,  7 Sep 2024 17:32:22 +0200

feat: better slots (ota entries) reading
chore: structs cleanup (own file)

Diffstat:
Msrc/helpers.rs | 15+++++++++++++++
Msrc/lib.rs | 56+++++++++++++++-----------------------------------------
Asrc/structs.rs | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 41 deletions(-)

diff --git a/src/helpers.rs b/src/helpers.rs @@ -16,3 +16,18 @@ pub fn seq_or_default(seq: &[u8], crc: u32, default: u32) -> u32 { default } + +#[inline(always)] +/// Helper function! +/// Check if crc is correct for given seq +pub fn is_crc_seq_correct(seq: u32, crc: u32) -> bool { + let bytes = unsafe { + let mut buf = [0; 4]; //u32 + core::ptr::copy_nonoverlapping(&seq as *const u32 as *const u8, buf.as_mut_ptr(), 4); + + buf + }; + + let crc_calc = crate::crc32::calc_crc32(&bytes, 0xFFFFFFFF); + crc == crc_calc +} diff --git a/src/lib.rs b/src/lib.rs @@ -7,49 +7,18 @@ compile_error!("You need to select at least one target: \"esp32c3\", \"esp32s2\", \"esp32s3\"."); use embedded_storage::{ReadStorage, Storage}; +pub use structs::*; pub mod crc32; pub mod helpers; pub mod paddr; +pub mod structs; const PART_OFFSET: u32 = 0x8000; const PART_SIZE: u32 = 0xc00; const FIRST_OTA_PART_SUBTYPE: u8 = 0x10; const OTA_VERIFY_READ_SIZE: usize = 256; -#[derive(Debug, PartialEq)] -pub enum OtaError { - NotEnoughPartitions, - OtaNotStarted, - FlashRWError, - WrongCRC, - WrongOTAPArtitionOrder, - OtaVerifyError, - NoNextOtaPartition, -} - -type Result<T> = core::result::Result<T, OtaError>; - -#[derive(Clone)] -pub struct FlashProgress { - last_crc: u32, - flash_offset: u32, - flash_size: u32, - remaining: u32, - - target_partition: usize, - 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> @@ -212,7 +181,8 @@ where /// Sets ota boot target partition pub fn set_target_ota_boot_partition(&mut self, target: usize) { - let (seq1, seq2) = self.get_ota_boot_sequences(); + let (slot1, slot2) = self.get_ota_boot_entries(); + let (seq1, seq2) = (slot1.seq, slot2.seq); let mut target_seq = seq1.max(seq2); while helpers::seq_to_part(target_seq, self.pinfo.ota_partitions_count) != target @@ -240,21 +210,25 @@ where /// Returns current OTA boot sequences /// /// NOTE: if crc doesn't match, it returns 0 for that seq - pub fn get_ota_boot_sequences(&mut self) -> (u32, u32) { + /// NOTE: [Entry struct (link to .h file)](https://github.com/espressif/esp-idf/blob/master/components/bootloader_support/include/esp_flash_partitions.h#L66) + pub fn get_ota_boot_entries(&mut self) -> (EspOtaSelectEntry, EspOtaSelectEntry) { let mut bytes = [0; 32]; - _ = 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); + let mut slot1: EspOtaSelectEntry = + unsafe { core::ptr::read(bytes.as_ptr() as *const EspOtaSelectEntry) }; + slot1.check_crc(); + log::info!("read slot1: {slot1:?}"); _ = 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); + let mut slot2: EspOtaSelectEntry = + unsafe { core::ptr::read(bytes.as_ptr() as *const EspOtaSelectEntry) }; + slot2.check_crc(); + log::info!("read slot2: {slot2:?}"); - (seq1, seq2) + (slot1, slot2) } /// Returns currently booted partition index diff --git a/src/structs.rs b/src/structs.rs @@ -0,0 +1,61 @@ +pub(crate) type Result<T> = core::result::Result<T, OtaError>; + +#[derive(Debug, PartialEq)] +pub enum OtaError { + NotEnoughPartitions, + OtaNotStarted, + FlashRWError, + WrongCRC, + WrongOTAPArtitionOrder, + OtaVerifyError, + NoNextOtaPartition, +} + +#[derive(Clone)] +pub struct FlashProgress { + pub last_crc: u32, + pub flash_offset: u32, + pub flash_size: u32, + pub remaining: u32, + + pub target_partition: usize, + pub target_crc: u32, +} + +#[derive(Debug)] +pub struct PartitionInfo { + pub ota_partitions: [(u32, u32); 16], + pub ota_partitions_count: usize, + + pub otadata_offset: u32, + pub otadata_size: u32, +} + +#[repr(u32)] +#[derive(Debug)] +pub enum OtaImgState { + EspOtaImgNew = 0x0, + EspOtaImgPendingVerify = 0x1, + EspOtaImgValid = 0x2, + EspOtaImgInvalid = 0x3, + EspOtaImgAborted = 0x4, + EspOtaImgUndefined = 0xFFFFFFFF, +} + +#[repr(C)] +#[derive(Debug)] +pub struct EspOtaSelectEntry { + pub seq: u32, + pub seq_label: [u8; 20], + pub ota_state: OtaImgState, + pub crc: u32, +} + +impl EspOtaSelectEntry { + /// Check if crc(of seq) is correct, if not - its setting seq to 0 + pub fn check_crc(&mut self) { + if !crate::helpers::is_crc_seq_correct(self.seq, self.crc) { + self.seq = 0; // set seq to 0 if crc not correct! + } + } +}