metapac: Concat contiguous memory regions for memory.x

This commit is contained in:
Dario Nieuwenhuis 2024-04-29 20:38:37 +02:00
parent 2dd60c7e0e
commit 18b3f334f4

View File

@ -415,48 +415,55 @@ fn gen_opts() -> generate::Options {
fn gen_memory_x(out_dir: &Path, chip: &Chip) { fn gen_memory_x(out_dir: &Path, chip: &Chip) {
let mut memory_x = String::new(); let mut memory_x = String::new();
let flash = chip let flash = get_memory_range(chip, MemoryRegionKind::Flash);
.memory let ram = get_memory_range(chip, MemoryRegionKind::Ram);
.iter()
.filter(|r| r.kind == MemoryRegionKind::Flash && r.name.starts_with("BANK_"));
let (flash_address, flash_size) = flash
.clone()
.map(|r| (r.address, r.size))
.reduce(|acc, el| (u32::min(acc.0, el.0), acc.1 + el.1))
.unwrap();
let ram = chip.memory.iter().find(|r| r.kind == MemoryRegionKind::Ram).unwrap();
let otp = chip
.memory
.iter()
.find(|r| r.kind == MemoryRegionKind::Flash && r.name == "OTP");
write!(memory_x, "MEMORY\n{{\n").unwrap(); write!(memory_x, "MEMORY\n{{\n").unwrap();
writeln!( writeln!(
memory_x, memory_x,
" FLASH : ORIGIN = 0x{:08x}, LENGTH = {:>4}K /* {} */", " FLASH : ORIGIN = 0x{:08x}, LENGTH = {:>4}K /* {} */",
flash_address, flash.0,
flash_size / 1024, flash.1 / 1024,
flash.map(|x| x.name.as_ref()).collect::<Vec<&str>>().join(" + ") flash.2
) )
.unwrap(); .unwrap();
writeln!( writeln!(
memory_x, memory_x,
" RAM : ORIGIN = 0x{:08x}, LENGTH = {:>4}K", " RAM : ORIGIN = 0x{:08x}, LENGTH = {:>4}K /* {} */",
ram.address, ram.0,
ram.size / 1024, ram.1 / 1024,
ram.2
) )
.unwrap(); .unwrap();
if let Some(otp) = otp {
writeln!(
memory_x,
" OTP : ORIGIN = 0x{:08x}, LENGTH = {:>4}",
otp.address, otp.size,
)
.unwrap();
}
write!(memory_x, "}}").unwrap(); write!(memory_x, "}}").unwrap();
fs::create_dir_all(out_dir.join("memory_x")).unwrap(); fs::create_dir_all(out_dir.join("memory_x")).unwrap();
let mut file = File::create(out_dir.join("memory_x").join("memory.x")).unwrap(); let mut file = File::create(out_dir.join("memory_x").join("memory.x")).unwrap();
file.write_all(memory_x.as_bytes()).unwrap(); file.write_all(memory_x.as_bytes()).unwrap();
} }
fn get_memory_range(chip: &Chip, kind: MemoryRegionKind) -> (u32, u32, String) {
let mut mems: Vec<_> = chip.memory.iter().filter(|m| m.kind == kind && m.size != 0).collect();
mems.sort_by_key(|m| m.address);
let mut start = u32::MAX;
let mut end = u32::MAX;
let mut names = Vec::new();
let mut best: Option<(u32, u32, String)> = None;
for m in mems {
if m.address != end {
names = Vec::new();
start = m.address;
end = m.address;
}
end += m.size;
names.push(m.name.to_string());
if best.is_none() || end - start > best.as_ref().unwrap().1 {
best = Some((start, end - start, names.join(" + ")));
}
}
best.unwrap()
}