stm32-metapac: add option to generate chip metadata as a rust const.
This commit is contained in:
parent
2cf79f6569
commit
4d73d87b40
97
stm32-metapac-gen/src/assets/metadata.rs
Normal file
97
stm32-metapac-gen/src/assets/metadata.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct Metadata {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub family: &'static str,
|
||||||
|
pub line: &'static str,
|
||||||
|
pub memory: &'static [MemoryRegion],
|
||||||
|
pub peripherals: &'static [Peripheral],
|
||||||
|
pub interrupts: &'static [Interrupt],
|
||||||
|
pub dma_channels: &'static [DmaChannel],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct MemoryRegion {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub kind: MemoryRegionKind,
|
||||||
|
pub address: u32,
|
||||||
|
pub size: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub enum MemoryRegionKind {
|
||||||
|
Flash,
|
||||||
|
Ram,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct Interrupt {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub number: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct Package {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub package: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct Peripheral {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub address: u64,
|
||||||
|
pub registers: Option<PeripheralRegisters>,
|
||||||
|
pub rcc: Option<PeripheralRcc>,
|
||||||
|
pub pins: &'static [PeripheralPin],
|
||||||
|
pub dma_channels: &'static [PeripheralDmaChannel],
|
||||||
|
pub interrupts: &'static [PeripheralInterrupt],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct PeripheralRegisters {
|
||||||
|
pub kind: &'static str,
|
||||||
|
pub version: &'static str,
|
||||||
|
pub block: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct PeripheralInterrupt {
|
||||||
|
pub signal: &'static str,
|
||||||
|
pub interrupt: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct PeripheralRcc {
|
||||||
|
pub clock: &'static str,
|
||||||
|
pub enable: Option<PeripheralRccRegister>,
|
||||||
|
pub reset: Option<PeripheralRccRegister>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct PeripheralRccRegister {
|
||||||
|
pub register: &'static str,
|
||||||
|
pub field: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct PeripheralPin {
|
||||||
|
pub pin: &'static str,
|
||||||
|
pub signal: &'static str,
|
||||||
|
pub af: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct DmaChannel {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub dma: &'static str,
|
||||||
|
pub channel: u32,
|
||||||
|
pub dmamux: Option<&'static str>,
|
||||||
|
pub dmamux_channel: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct PeripheralDmaChannel {
|
||||||
|
pub signal: &'static str,
|
||||||
|
pub channel: Option<&'static str>,
|
||||||
|
pub dmamux: Option<&'static str>,
|
||||||
|
pub request: Option<u32>,
|
||||||
|
}
|
@ -16,6 +16,17 @@ use chiptool::{generate, ir, transform};
|
|||||||
mod data;
|
mod data;
|
||||||
use data::*;
|
use data::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
struct Metadata<'a> {
|
||||||
|
name: &'a str,
|
||||||
|
family: &'a str,
|
||||||
|
line: &'a str,
|
||||||
|
memory: &'a [MemoryRegion],
|
||||||
|
peripherals: &'a [Peripheral],
|
||||||
|
interrupts: &'a [Interrupt],
|
||||||
|
dma_channels: &'a [DmaChannel],
|
||||||
|
}
|
||||||
|
|
||||||
fn make_peripheral_counts(out: &mut String, data: &BTreeMap<String, u8>) {
|
fn make_peripheral_counts(out: &mut String, data: &BTreeMap<String, u8>) {
|
||||||
write!(
|
write!(
|
||||||
out,
|
out,
|
||||||
@ -384,12 +395,7 @@ pub fn gen_chip(
|
|||||||
let mut device_x = String::new();
|
let mut device_x = String::new();
|
||||||
|
|
||||||
for irq in &core.interrupts {
|
for irq in &core.interrupts {
|
||||||
write!(
|
write!(&mut device_x, "PROVIDE({} = DefaultHandler);\n", irq.name).unwrap();
|
||||||
&mut device_x,
|
|
||||||
"PROVIDE({} = DefaultHandler);\n",
|
|
||||||
irq.name.to_ascii_uppercase()
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
@ -397,6 +403,7 @@ pub fn gen_chip(
|
|||||||
|
|
||||||
let mut data = String::new();
|
let mut data = String::new();
|
||||||
|
|
||||||
|
write!(&mut data, "#[cfg(feature=\"metadata\")] pub mod metadata;").unwrap();
|
||||||
write!(&mut data, "#[cfg(feature=\"pac\")] mod pac;").unwrap();
|
write!(&mut data, "#[cfg(feature=\"pac\")] mod pac;").unwrap();
|
||||||
write!(&mut data, "#[cfg(feature=\"pac\")] pub use pac::*; ").unwrap();
|
write!(&mut data, "#[cfg(feature=\"pac\")] pub use pac::*; ").unwrap();
|
||||||
|
|
||||||
@ -424,6 +431,38 @@ pub fn gen_chip(
|
|||||||
let mut file = File::create(chip_dir.join("mod.rs")).unwrap();
|
let mut file = File::create(chip_dir.join("mod.rs")).unwrap();
|
||||||
file.write_all(data.as_bytes()).unwrap();
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
// ==============================
|
||||||
|
// generate metadata.rs
|
||||||
|
|
||||||
|
let metadata = Metadata {
|
||||||
|
name: &chip.name,
|
||||||
|
family: &chip.family,
|
||||||
|
line: &chip.line,
|
||||||
|
memory: &chip.memory,
|
||||||
|
peripherals: &core.peripherals,
|
||||||
|
interrupts: &core.interrupts,
|
||||||
|
dma_channels: &core.dma_channels,
|
||||||
|
};
|
||||||
|
let metadata = format!("{:#?}", metadata);
|
||||||
|
let metadata = metadata.replace("[\n", "&[\n");
|
||||||
|
let metadata = metadata.replace("[],\n", "&[],\n");
|
||||||
|
|
||||||
|
let mut data = String::new();
|
||||||
|
|
||||||
|
write!(
|
||||||
|
&mut data,
|
||||||
|
"
|
||||||
|
include!(\"../../metadata.rs\");
|
||||||
|
use MemoryRegionKind::*;
|
||||||
|
pub const METADATA: Metadata = {};
|
||||||
|
",
|
||||||
|
metadata
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut file = File::create(chip_dir.join("metadata.rs")).unwrap();
|
||||||
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
// generate device.x
|
// generate device.x
|
||||||
|
|
||||||
@ -462,7 +501,21 @@ pub fn gen(options: Options) {
|
|||||||
for chip_name in &options.chips {
|
for chip_name in &options.chips {
|
||||||
println!("Generating {}...", chip_name);
|
println!("Generating {}...", chip_name);
|
||||||
|
|
||||||
let chip = load_chip(&options, chip_name);
|
let mut chip = load_chip(&options, chip_name);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
for core in &mut chip.cores {
|
||||||
|
for irq in &mut core.interrupts {
|
||||||
|
irq.name = irq.name.to_ascii_uppercase();
|
||||||
|
}
|
||||||
|
for p in &mut core.peripherals {
|
||||||
|
for irq in &mut p.interrupts {
|
||||||
|
irq.interrupt = irq.interrupt.to_ascii_uppercase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate
|
||||||
for (core_index, core) in chip.cores.iter().enumerate() {
|
for (core_index, core) in chip.cores.iter().enumerate() {
|
||||||
let chip_core_name = match chip.cores.len() {
|
let chip_core_name = match chip.cores.len() {
|
||||||
1 => chip_name.clone(),
|
1 => chip_name.clone(),
|
||||||
@ -557,6 +610,13 @@ pub fn gen(options: Options) {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// Generate src/metadata.rs
|
||||||
|
fs::write(
|
||||||
|
options.out_dir.join("src").join("metadata.rs"),
|
||||||
|
include_bytes!("assets/metadata.rs"),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Generate Cargo.toml
|
// Generate Cargo.toml
|
||||||
const BUILDDEP_BEGIN: &[u8] = b"# BEGIN BUILD DEPENDENCIES";
|
const BUILDDEP_BEGIN: &[u8] = b"# BEGIN BUILD DEPENDENCIES";
|
||||||
const BUILDDEP_END: &[u8] = b"# END BUILD DEPENDENCIES";
|
const BUILDDEP_END: &[u8] = b"# END BUILD DEPENDENCIES";
|
||||||
|
@ -19,10 +19,14 @@ regex = "1.5.4"
|
|||||||
default = ["pac"]
|
default = ["pac"]
|
||||||
|
|
||||||
# Build the actual PAC. Set by default.
|
# Build the actual PAC. Set by default.
|
||||||
# If not set, only the macrotables will be generated. You may want to not set it
|
# If you just want the metadata, unset it with `default-features = false`.
|
||||||
# if you're using stm32-metapac from a build.rs script to use the macros.
|
|
||||||
pac = []
|
pac = []
|
||||||
|
|
||||||
|
# Build the chip metadata.
|
||||||
|
# If set, a const `stm32_metapac::METADATA` will be exported, containing all the
|
||||||
|
# metadata for the currently selected chip.
|
||||||
|
metadata = []
|
||||||
|
|
||||||
rt = ["cortex-m-rt/device"]
|
rt = ["cortex-m-rt/device"]
|
||||||
memory-x = []
|
memory-x = []
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user