Fix memory various region generation bugs
This commit is contained in:
parent
b9d1c2a2ab
commit
9e0a4b153e
@ -983,7 +983,9 @@ fn process_chip(
|
|||||||
cores: &[stm32_data_serde::chip::Core],
|
cores: &[stm32_data_serde::chip::Core],
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
let chip = chips.get(chip_name).unwrap();
|
let chip = chips.get(chip_name).unwrap();
|
||||||
let flash_total = chip.flash * 1024;
|
let flash_size = chip.flash * 1024;
|
||||||
|
let mut flash_remaining = flash_size;
|
||||||
|
let flash_regions = memories.determine_flash_regions(chip_name, flash_size);
|
||||||
let ram_total = chip.ram * 1024;
|
let ram_total = chip.ram * 1024;
|
||||||
let mut memory_regions = Vec::new();
|
let mut memory_regions = Vec::new();
|
||||||
let mut found = HashSet::<&str>::new();
|
let mut found = HashSet::<&str>::new();
|
||||||
@ -996,11 +998,15 @@ fn process_chip(
|
|||||||
"D1_AXIICP",
|
"D1_AXIICP",
|
||||||
] {
|
] {
|
||||||
if let Some(address) = h.defines.get("all").unwrap().0.get(&format!("{each}_BASE")) {
|
if let Some(address) = h.defines.get("all").unwrap().0.get(&format!("{each}_BASE")) {
|
||||||
let key = match each {
|
let (key, banks) = match each {
|
||||||
"FLASH" => "BANK1",
|
"FLASH" => (
|
||||||
"FLASH_BANK1" => "BANK1",
|
"BANK_1",
|
||||||
"FLASH_BANK2" => "BANK2",
|
Some([memory::FlashBank::Bank1, memory::FlashBank::Bank2].as_ref()),
|
||||||
each => each,
|
),
|
||||||
|
"FLASH_BANK1" => ("BANK_1", Some([memory::FlashBank::Bank1].as_ref())),
|
||||||
|
"FLASH_BANK2" => ("BANK_2", Some([memory::FlashBank::Bank2].as_ref())),
|
||||||
|
"FLASH_OTP" => ("OTP", Some([memory::FlashBank::Otp].as_ref())),
|
||||||
|
each => (each, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
if found.contains(key) {
|
if found.contains(key) {
|
||||||
@ -1008,46 +1014,59 @@ fn process_chip(
|
|||||||
}
|
}
|
||||||
found.insert(key);
|
found.insert(key);
|
||||||
|
|
||||||
if key == "FLASH_OTP" {
|
if let Some(banks) = banks {
|
||||||
if let Some(region) = memories
|
for bank in banks {
|
||||||
.determine_flash_regions(chip_name)
|
let bank_name = match bank {
|
||||||
.iter()
|
memory::FlashBank::Bank1 => "BANK_1",
|
||||||
.find(|x| x.bank == memory::FlashBank::Otp)
|
memory::FlashBank::Bank2 => "BANK_2",
|
||||||
{
|
memory::FlashBank::Otp => "OTP",
|
||||||
memory_regions.push(stm32_data_serde::chip::Memory {
|
};
|
||||||
name: region.name.clone(),
|
let regions: Vec<_> = flash_regions
|
||||||
kind: stm32_data_serde::chip::memory::Kind::Otp,
|
.iter()
|
||||||
address: u32::try_from(*address).unwrap(),
|
.filter(|region| region.bank == *bank)
|
||||||
size: region.bytes,
|
.enumerate()
|
||||||
settings: Some(region.settings.clone()),
|
.map_while(|(index, region)| {
|
||||||
})
|
let size = if *bank == memory::FlashBank::Bank1 || *bank == memory::FlashBank::Bank2 {
|
||||||
|
// Truncate region to the total amount of remaining chip flash
|
||||||
|
let size = std::cmp::min(region.bytes, flash_remaining);
|
||||||
|
flash_remaining -= size;
|
||||||
|
if size == 0 {
|
||||||
|
// No more regions are present on this chip
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
size
|
||||||
|
} else {
|
||||||
|
region.bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((index, region.address, size, region.settings.clone()))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let has_multiple_regions = regions.len() > 1;
|
||||||
|
for (index, address, size, settings) in regions {
|
||||||
|
let name = if has_multiple_regions {
|
||||||
|
format!("{}_REGION_{}", bank_name, index + 1)
|
||||||
|
} else {
|
||||||
|
bank_name.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
memory_regions.push(stm32_data_serde::chip::Memory {
|
||||||
|
name,
|
||||||
|
kind: stm32_data_serde::chip::memory::Kind::Flash,
|
||||||
|
address,
|
||||||
|
size,
|
||||||
|
settings: Some(settings.clone()),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let bank = if key == "BANK2" {
|
memory_regions.push(stm32_data_serde::chip::Memory {
|
||||||
memory::FlashBank::Bank2
|
name: key.to_string(),
|
||||||
} else {
|
kind: stm32_data_serde::chip::memory::Kind::Flash,
|
||||||
memory::FlashBank::Bank1
|
address: u32::try_from(*address).unwrap(),
|
||||||
};
|
size: 0,
|
||||||
|
settings: None,
|
||||||
for region in memories
|
})
|
||||||
.determine_flash_regions(chip_name)
|
|
||||||
.iter()
|
|
||||||
.filter(|x| x.bank == bank)
|
|
||||||
{
|
|
||||||
let size = if key == "BANK1" || key == "BANK2" {
|
|
||||||
std::cmp::min(region.bytes, flash_total)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
memory_regions.push(stm32_data_serde::chip::Memory {
|
|
||||||
name: format!("{}_{}", key, region.name),
|
|
||||||
kind: stm32_data_serde::chip::memory::Kind::Flash,
|
|
||||||
address: u32::try_from(*address).unwrap(),
|
|
||||||
size,
|
|
||||||
settings: Some(region.settings.clone()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1077,7 +1096,7 @@ fn process_chip(
|
|||||||
found.insert(key);
|
found.insert(key);
|
||||||
|
|
||||||
let size = if key == "SRAM" {
|
let size = if key == "SRAM" {
|
||||||
let size = memories.determine_ram_size(chip_name);
|
let size = memories.determine_ram_size(chip_name, flash_size);
|
||||||
std::cmp::min(size, ram_total)
|
std::cmp::min(size, ram_total)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
@ -1093,7 +1112,7 @@ fn process_chip(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let docs = docs.documents_for(chip_name);
|
let docs = docs.documents_for(chip_name);
|
||||||
let device_id = memories.determine_device_id(chip_name);
|
let device_id = memories.determine_device_id(chip_name, flash_size);
|
||||||
let chip = stm32_data_serde::Chip {
|
let chip = stm32_data_serde::Chip {
|
||||||
name: chip_name.to_string(),
|
name: chip_name.to_string(),
|
||||||
family: group.family.clone().unwrap(),
|
family: group.family.clone().unwrap(),
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use std::fs;
|
use std::{cmp::Ordering, fs};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct Memory {
|
struct Memory {
|
||||||
pub device_id: u16,
|
pub device_id: u16,
|
||||||
pub names: Vec<String>,
|
pub names: Vec<String>,
|
||||||
pub ram: Ram,
|
pub ram: Ram,
|
||||||
pub flash: Vec<FlashRegion>,
|
pub flash_size: u32,
|
||||||
|
pub flash_regions: Vec<FlashRegion>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
@ -17,7 +18,6 @@ struct Ram {
|
|||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct FlashRegion {
|
pub struct FlashRegion {
|
||||||
pub bank: FlashBank,
|
pub bank: FlashBank,
|
||||||
pub name: String,
|
|
||||||
pub address: u32,
|
pub address: u32,
|
||||||
pub bytes: u32,
|
pub bytes: u32,
|
||||||
pub settings: stm32_data_serde::chip::memory::Settings,
|
pub settings: stm32_data_serde::chip::memory::Settings,
|
||||||
@ -214,7 +214,6 @@ impl Memories {
|
|||||||
paths.sort();
|
paths.sort();
|
||||||
|
|
||||||
let mut memories = Vec::new();
|
let mut memories = Vec::new();
|
||||||
let alphabet: Vec<char> = (b'A'..=b'Z').map(|c| c as char).collect();
|
|
||||||
|
|
||||||
for f in paths {
|
for f in paths {
|
||||||
// println!("Parsing {f:?}");
|
// println!("Parsing {f:?}");
|
||||||
@ -226,9 +225,10 @@ impl Memories {
|
|||||||
let names = split_names(&parsed.device.name);
|
let names = split_names(&parsed.device.name);
|
||||||
|
|
||||||
let mut ram = None;
|
let mut ram = None;
|
||||||
let mut flash = vec![];
|
let mut flash_size = None;
|
||||||
|
let mut flash_regions = vec![];
|
||||||
|
|
||||||
for peripheral in parsed.device.peripherals.peripharal {
|
for mut peripheral in parsed.device.peripherals.peripharal {
|
||||||
if peripheral.name == "Embedded SRAM" && ram.is_none() {
|
if peripheral.name == "Embedded SRAM" && ram.is_none() {
|
||||||
let config = peripheral.configuration.first().unwrap();
|
let config = peripheral.configuration.first().unwrap();
|
||||||
let parameters = config.parameters.as_ref().unwrap();
|
let parameters = config.parameters.as_ref().unwrap();
|
||||||
@ -249,49 +249,63 @@ impl Memories {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(kind) = kind {
|
if let Some(kind) = kind {
|
||||||
// Use single bank alignment if both single and dual is available
|
peripheral.configuration.sort_by(|a, b| {
|
||||||
let config = peripheral
|
// Prefer largest size
|
||||||
.configuration
|
let ordering = b
|
||||||
.iter()
|
.parameters
|
||||||
.find(|c| c.organization.as_ref().map(|x| x.as_str()).unwrap_or_default() == "Single")
|
.as_ref()
|
||||||
.unwrap_or_else(|| peripheral.configuration.first().unwrap());
|
.unwrap()
|
||||||
let parameters = config.parameters.as_ref().unwrap();
|
.size
|
||||||
let bank = config.bank.first().unwrap();
|
.partial_cmp(&a.parameters.as_ref().unwrap().size)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let flash_bank = match kind {
|
// ... then prefer single ordering over dual
|
||||||
BlockKind::Main => match bank.name.as_ref().map(|x| x.as_str()) {
|
if ordering == Ordering::Equal {
|
||||||
Some("Bank 1") => FlashBank::Bank1,
|
// Possible values are Single and Dual
|
||||||
Some("Bank 2") => FlashBank::Bank2,
|
b.organization.partial_cmp(&a.organization).unwrap()
|
||||||
None => FlashBank::Bank1,
|
|
||||||
_ => unimplemented!(),
|
|
||||||
},
|
|
||||||
BlockKind::Otp => FlashBank::Otp,
|
|
||||||
};
|
|
||||||
|
|
||||||
let erase_value = peripheral.erased_value.unwrap();
|
|
||||||
let write_size = config.allignement.unwrap();
|
|
||||||
flash.extend(bank.field.iter().enumerate().map(|(index, field)| {
|
|
||||||
let name = match kind {
|
|
||||||
BlockKind::Main => format!("MAIN{}", alphabet[index]).to_string(),
|
|
||||||
BlockKind::Otp => "OTP".to_string(),
|
|
||||||
};
|
|
||||||
let bytes = if let Some(occurence) = field.parameters.occurence {
|
|
||||||
occurence * field.parameters.size
|
|
||||||
} else {
|
} else {
|
||||||
parameters.size
|
ordering
|
||||||
};
|
|
||||||
FlashRegion {
|
|
||||||
bank: flash_bank,
|
|
||||||
name,
|
|
||||||
address: field.parameters.address,
|
|
||||||
bytes,
|
|
||||||
settings: stm32_data_serde::chip::memory::Settings {
|
|
||||||
erase_value,
|
|
||||||
write_size,
|
|
||||||
erase_size: field.parameters.size,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
let config = peripheral.configuration.first().unwrap();
|
||||||
|
|
||||||
|
if flash_size.is_none() {
|
||||||
|
let parameters = config.parameters.as_ref().unwrap();
|
||||||
|
|
||||||
|
flash_size = Some(parameters.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
for bank in config.bank.iter() {
|
||||||
|
let flash_bank = match kind {
|
||||||
|
BlockKind::Main => match bank.name.as_ref().map(|x| x.as_str()) {
|
||||||
|
Some("Bank 1") => Some(FlashBank::Bank1),
|
||||||
|
Some("Bank 2") => Some(FlashBank::Bank2),
|
||||||
|
Some("EEPROM1") => None,
|
||||||
|
Some("EEPROM2") => None,
|
||||||
|
None => {
|
||||||
|
assert_eq!(1, config.bank.len());
|
||||||
|
Some(FlashBank::Bank1)
|
||||||
|
}
|
||||||
|
Some(other) => unimplemented!("Unsupported flash bank {}", other),
|
||||||
|
},
|
||||||
|
BlockKind::Otp => Some(FlashBank::Otp),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(flash_bank) = flash_bank {
|
||||||
|
let erase_value = peripheral.erased_value.unwrap();
|
||||||
|
let write_size = config.allignement.unwrap();
|
||||||
|
flash_regions.extend(bank.field.iter().map(|field| FlashRegion {
|
||||||
|
bank: flash_bank,
|
||||||
|
address: field.parameters.address,
|
||||||
|
bytes: field.parameters.occurence.unwrap() * field.parameters.size,
|
||||||
|
settings: stm32_data_serde::chip::memory::Settings {
|
||||||
|
erase_value,
|
||||||
|
write_size,
|
||||||
|
erase_size: field.parameters.size,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +313,8 @@ impl Memories {
|
|||||||
device_id,
|
device_id,
|
||||||
names,
|
names,
|
||||||
ram: ram.unwrap(),
|
ram: ram.unwrap(),
|
||||||
flash,
|
flash_size: flash_size.unwrap_or_default(),
|
||||||
|
flash_regions,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,9 +326,9 @@ impl Memories {
|
|||||||
address: 0x20000000,
|
address: 0x20000000,
|
||||||
bytes: 64 * 1024,
|
bytes: 64 * 1024,
|
||||||
},
|
},
|
||||||
flash: vec![FlashRegion {
|
flash_size: 384 * 1024,
|
||||||
|
flash_regions: vec![FlashRegion {
|
||||||
bank: FlashBank::Bank1,
|
bank: FlashBank::Bank1,
|
||||||
name: "MAINA".to_string(),
|
|
||||||
address: 0x08000000,
|
address: 0x08000000,
|
||||||
bytes: 384 * 1024,
|
bytes: 384 * 1024,
|
||||||
settings: stm32_data_serde::chip::memory::Settings {
|
settings: stm32_data_serde::chip::memory::Settings {
|
||||||
@ -331,9 +346,9 @@ impl Memories {
|
|||||||
address: 0x20000000,
|
address: 0x20000000,
|
||||||
bytes: 80 * 1024,
|
bytes: 80 * 1024,
|
||||||
},
|
},
|
||||||
flash: vec![FlashRegion {
|
flash_size: 384 * 1024,
|
||||||
|
flash_regions: vec![FlashRegion {
|
||||||
bank: FlashBank::Bank1,
|
bank: FlashBank::Bank1,
|
||||||
name: "MAINA".to_string(),
|
|
||||||
address: 0x08000000,
|
address: 0x08000000,
|
||||||
bytes: 384 * 1024,
|
bytes: 384 * 1024,
|
||||||
settings: stm32_data_serde::chip::memory::Settings {
|
settings: stm32_data_serde::chip::memory::Settings {
|
||||||
@ -349,45 +364,54 @@ impl Memories {
|
|||||||
names: vec!["STM32L100x6".to_string()],
|
names: vec!["STM32L100x6".to_string()],
|
||||||
ram: Ram {
|
ram: Ram {
|
||||||
address: 0x20000000,
|
address: 0x20000000,
|
||||||
bytes: 32 * 1024,
|
|
||||||
},
|
|
||||||
flash: vec![FlashRegion {
|
|
||||||
bank: FlashBank::Bank1,
|
|
||||||
name: "MAINA".to_string(),
|
|
||||||
address: 0x08000000,
|
|
||||||
bytes: 4 * 1024,
|
bytes: 4 * 1024,
|
||||||
|
},
|
||||||
|
flash_size: 32 * 1024,
|
||||||
|
flash_regions: vec![FlashRegion {
|
||||||
|
bank: FlashBank::Bank1,
|
||||||
|
address: 0x08000000,
|
||||||
|
bytes: 32 * 1024,
|
||||||
settings: stm32_data_serde::chip::memory::Settings {
|
settings: stm32_data_serde::chip::memory::Settings {
|
||||||
erase_value: 0xFF,
|
|
||||||
write_size: 4,
|
|
||||||
erase_size: 256,
|
erase_size: 256,
|
||||||
|
write_size: 4,
|
||||||
|
erase_value: 0xFF,
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Sort memories by flash size in descending order so that when we look
|
||||||
|
// a chip up later by name, the it will find the one with the largest flash size.
|
||||||
|
memories.sort_by(|a, b| b.flash_size.cmp(&a.flash_size));
|
||||||
|
|
||||||
Ok(Self(memories))
|
Ok(Self(memories))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_chip(&self, chip_name: &str) -> &Memory {
|
fn lookup_chip(&self, chip_name: &str, flash_size: u32) -> &Memory {
|
||||||
|
// We use here that the memories are sorted in descending order by flash size.
|
||||||
|
// We emit the memory for which which the regions include at least the flash size of the requested chip.
|
||||||
for each in &self.0 {
|
for each in &self.0 {
|
||||||
for name in &each.names {
|
if each.flash_size >= flash_size {
|
||||||
if is_chip_name_match(name, chip_name) {
|
for name in &each.names {
|
||||||
return each;
|
if is_chip_name_match(name, chip_name) {
|
||||||
|
return each;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic!("could not find memory information for {chip_name}");
|
|
||||||
|
panic!("could not find memory information for {chip_name} with flash size {flash_size}");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn determine_ram_size(&self, chip_name: &str) -> u32 {
|
pub fn determine_ram_size(&self, chip_name: &str, flash_size: u32) -> u32 {
|
||||||
self.lookup_chip(chip_name).ram.bytes
|
self.lookup_chip(chip_name, flash_size).ram.bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn determine_flash_regions(&self, chip_name: &str) -> &[FlashRegion] {
|
pub fn determine_flash_regions(&self, chip_name: &str, flash_size: u32) -> &[FlashRegion] {
|
||||||
self.lookup_chip(chip_name).flash.as_slice()
|
self.lookup_chip(chip_name, flash_size).flash_regions.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn determine_device_id(&self, chip_name: &str) -> u16 {
|
pub fn determine_device_id(&self, chip_name: &str, flash_size: u32) -> u16 {
|
||||||
self.lookup_chip(chip_name).device_id
|
self.lookup_chip(chip_name, flash_size).device_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ pub mod chip {
|
|||||||
pub enum Kind {
|
pub enum Kind {
|
||||||
Flash,
|
Flash,
|
||||||
Ram,
|
Ram,
|
||||||
Otp,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user