Support "flashing" program data to RAM
use super::{FlashBuilder, FlashError, FlashProgress, Flasher};
use crate::config::{FlashRegion, MemoryRange, MemoryRegion};
+use crate::memory::MemoryInterface;
use crate::session::Session;
use anyhow::anyhow;
use std::collections::HashMap;
+struct RamWrite<'data> {
+ address: u32,
+ data: &'data [u8],
+}
+
/// `FlashLoader` is a struct which manages the flashing of any chunks of data onto any sections of flash.
/// Use `add_data()` to add a chunks of data.
/// Once you are done adding all your data, use `commit()` to flash the data.
@@ -12,6 +18,7 @@ use std::collections::HashMap;
pub(super) struct FlashLoader<'mmap, 'data> {
memory_map: &'mmap [MemoryRegion],
builders: HashMap<FlashRegion, FlashBuilder<'data>>,
+ ram_write: Vec<RamWrite<'data>>,
keep_unwritten: bool,
}
@@ -20,6 +27,7 @@ impl<'mmap, 'data> FlashLoader<'mmap, 'data> {
Self {
memory_map,
builders: HashMap::new(),
+ ram_write: Vec::new(),
keep_unwritten,
}
}
@@ -37,7 +45,8 @@ impl<'mmap, 'data> FlashLoader<'mmap, 'data> {
// Get the flash region in with this chunk of data starts.
let possible_region = Self::get_region_for_address(self.memory_map, address);
// If we found a corresponding region, create a builder.
- if let Some(MemoryRegion::Flash(region)) = possible_region {
+ match possible_region {
+ Some(MemoryRegion::Flash(region)) => {
// Get our builder instance.
if !self.builders.contains_key(region) {
self.builders.insert(region.clone(), FlashBuilder::new());
@@ -54,12 +63,27 @@ impl<'mmap, 'data> FlashLoader<'mmap, 'data> {
// Advance the cursors.
remaining -= program_length;
- address += program_length as u32;
- } else {
+ address += program_length as u32
+ }
+ Some(MemoryRegion::Ram(region)) => {
+ // Determine how much more data can be contained by this region.
+ let program_length =
+ usize::min(remaining, (region.range.end - address + 1) as usize);
+
+ // Add data to be written to the vector.
+ let data = &data[size - remaining..program_length];
+ self.ram_write.push(RamWrite { address, data });
+
+ // Advance the cursors.
+ remaining -= program_length;
+ address += program_length as u32
+ }
+ _ => {
return Err(FlashError::NoSuitableFlash {
start: address,
end: address + data.len() as u32,
- });
+ })
+ }
}
}
Ok(())
@@ -151,6 +175,21 @@ impl<'mmap, 'data> FlashLoader<'mmap, 'data> {
flasher.program(builder, do_chip_erase, self.keep_unwritten, false, progress)?
}
+ // Write data to ram.
+
+ // Attach to memory and core.
+ let mut core = session.core(0).map_err(FlashError::Memory)?;
+
+ for RamWrite { address, data } in &self.ram_write {
+ log::info!(
+ "Ram write program data @ {:X} {} bytes",
+ *address,
+ data.len()
+ );
+ // Write data to memory.
+ core.write_8(*address, data).map_err(FlashError::Memory)?;
+ }
+
Ok(())
}
}
