diff --git a/blflash/src/flasher.rs b/blflash/src/flasher.rs index daa3708..faa50cd 100644 --- a/blflash/src/flasher.rs +++ b/blflash/src/flasher.rs @@ -38,15 +38,25 @@ impl Flasher { &self.boot_info } - pub fn load_segments<'a>(&'a mut self, segments: impl Iterator>) -> Result<(), Error> { + pub fn load_segments<'a>(&'a mut self, force: bool, segments: impl Iterator>) -> Result<(), Error> { self.load_eflash_loader()?; self.connection.set_baud(BaudRate::BaudOther(2_000_000))?; self.handshake()?; for segment in segments { + let local_hash = Sha256::digest(&segment.data[0..segment.size() as usize]); + + // skip segment if the contents are matched + if !force { + let sha256 = self.sha256_read(segment.addr, segment.size())?; + if sha256 == &local_hash[..] { + log::info!("Skip segment addr: {:x} size: {} sha256 matches", segment.addr, segment.size()); + continue + } + } + log::info!("Erase flash addr: {:x} size: {}", segment.addr, segment.size()); self.flash_erase(segment.addr, segment.addr + segment.size())?; - let local_hash = Sha256::digest(&segment.data[0..segment.size() as usize]); let mut reader = Cursor::new(&segment.data); let mut cur = segment.addr; @@ -90,14 +100,14 @@ impl Flasher { Ok(()) } - pub fn load_elf_to_flash(&mut self, elf_data: &[u8]) -> Result<(), Error> { + pub fn load_elf_to_flash(&mut self, force: bool, elf_data: &[u8]) -> Result<(), Error> { let image = FirmwareImage::from_data(elf_data).map_err(|_| Error::InvalidElf)?; let segs = image .segments() .filter_map(|segment| self.chip.get_flash_segment(segment)) .collect::>(); - self.load_segments(segs.into_iter())?; + self.load_segments(force, segs.into_iter())?; Ok(()) } diff --git a/blflash/src/main.rs b/blflash/src/main.rs index 9516d29..f43de18 100644 --- a/blflash/src/main.rs +++ b/blflash/src/main.rs @@ -24,6 +24,9 @@ struct FlashOpt { /// With boot2 #[structopt(short, long)] without_boot2: bool, + /// Don't skip if hash matches + #[structopt(short, long)] + force: bool, } #[derive(StructOpt)] @@ -75,7 +78,7 @@ fn flash(opt: FlashOpt) -> Result<(), Error> { log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version); log::trace!("Boot info: {:x?}", flasher.boot_info()); - flasher.load_segments(segments.into_iter())?; + flasher.load_segments(opt.force, segments.into_iter())?; flasher.reset()?; } else { @@ -89,7 +92,7 @@ fn flash(opt: FlashOpt) -> Result<(), Error> { log::trace!("Boot info: {:x?}", flasher.boot_info()); let input_bytes = read(&opt.image)?; - flasher.load_elf_to_flash(&input_bytes)?; + flasher.load_elf_to_flash(opt.force, &input_bytes)?; flasher.reset()?; }