Skip to content

Commit

Permalink
mmaps: fields coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Aug 11, 2024
1 parent f30e86b commit e5ab476
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This changelog tracks the Rust `svdtools` project. See

## [Unreleased]

* Show number of covered fields in `mmaps`
* Sugar for simple `_split` and `_merge`

## [v0.3.18] 2024-08-10
Expand Down
96 changes: 86 additions & 10 deletions src/mmap/mmap_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ use anyhow::{Context, Result};
use std::{fs::File, io::Read, path::Path};
use svd::PeripheralInfo;
use svd_parser::svd::{self, Cluster, Field, Peripheral, Register, RegisterCluster, RegisterInfo};
use svd_rs::FieldInfo;

#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
struct CoveredFields {
all: u32,
covered: u32,
}

/// Output sorted text of every peripheral, register, field, and interrupt
/// in the device, such that automated diffing is possible.
Expand All @@ -28,28 +35,46 @@ fn get_text<R: Read>(svd: &mut R) -> Result<String> {

fn to_text(peripherals: &[Peripheral]) -> String {
let mut mmap: Vec<String> = vec![];
let mut coverage = CoveredFields::default();

for p in peripherals {
match p {
Peripheral::Single(p) => {
get_peripheral(p, &mut mmap);
get_interrupts(p, &mut mmap);
let registers = get_periph_registers(p, peripherals);
get_registers(p.base_address, registers.as_ref(), "", &mut mmap);
get_registers(
p.base_address,
registers.as_ref(),
"",
&mut mmap,
&mut coverage,
);
}
Peripheral::Array(p, d) => {
for pi in svd::peripheral::expand(p, d) {
get_peripheral(&pi, &mut mmap);
get_interrupts(&pi, &mut mmap);
let registers = get_periph_registers(&pi, peripherals);
get_registers(pi.base_address, registers.as_ref(), "", &mut mmap);
get_registers(
pi.base_address,
registers.as_ref(),
"",
&mut mmap,
&mut coverage,
);
}
}
}
}

mmap.sort();
mmap.join("\n")
let mut mmap = mmap.join("\n");
mmap.push_str(&format!(
"\nCovered {} from {} fields.",
coverage.covered, coverage.all
));
mmap
}

fn get_periph_registers<'a>(
Expand Down Expand Up @@ -104,6 +129,7 @@ fn get_registers(
registers: Option<&Vec<RegisterCluster>>,
suffix: &str,
mmap: &mut Vec<String>,
coverage: &mut CoveredFields,
) {
if let Some(registers) = registers {
for r in registers {
Expand All @@ -121,7 +147,7 @@ fn get_registers(
"{addr} B REGISTER {rname}{derived}{access}: {description}"
);
mmap.push(text);
get_fields(r, &addr, mmap);
get_fields(r, &addr, mmap, coverage);
}
Register::Array(r, d) => {
for ri in svd::register::expand(r, d) {
Expand All @@ -134,7 +160,7 @@ fn get_registers(
"{addr} B REGISTER {rname}{derived}{access}: {description}"
);
mmap.push(text);
get_fields(&ri, &addr, mmap);
get_fields(&ri, &addr, mmap, coverage);
}
}
}
Expand All @@ -149,7 +175,7 @@ fn get_registers(
let description = str_utils::get_description(&c.description);
let text = format!("{addr} B CLUSTER {cname}{derived}: {description}");
mmap.push(text);
get_registers(caddr, Some(&c.children), "", mmap);
get_registers(caddr, Some(&c.children), "", mmap, coverage);
}
Cluster::Array(c, d) => {
for (ci, idx) in svd::cluster::expand(c, d).zip(d.indexes()) {
Expand All @@ -160,7 +186,7 @@ fn get_registers(
let text =
format!("{addr} B CLUSTER {cname}{derived}: {description}");
mmap.push(text);
get_registers(caddr, Some(&c.children), &idx, mmap);
get_registers(caddr, Some(&c.children), &idx, mmap, coverage);
}
}
}
Expand All @@ -170,7 +196,12 @@ fn get_registers(
}
}

fn get_fields(register: &RegisterInfo, addr: &str, mmap: &mut Vec<String>) {
fn get_fields(
register: &RegisterInfo,
addr: &str,
mmap: &mut Vec<String>,
coverage: &mut CoveredFields,
) {
if let Some(fields) = &register.fields {
for f in fields {
let derived = derived_str(&f.derived_from);
Expand All @@ -185,6 +216,12 @@ fn get_fields(register: &RegisterInfo, addr: &str, mmap: &mut Vec<String>) {
"{addr} C FIELD {bit_offset:02}w{bit_width:02} {fname}{derived}{access}: {description}"
);
mmap.push(text);
if f.derived_from.is_none() {
coverage.all += 1;
if is_covered(f) {
coverage.covered += 1;
}
}
}
Field::Array(f, d) => {
for fi in svd::field::expand(f, d) {
Expand All @@ -195,14 +232,24 @@ fn get_fields(register: &RegisterInfo, addr: &str, mmap: &mut Vec<String>) {
let text = format!(
"{addr} C FIELD {bit_offset:02}w{bit_width:02} {fname}{derived}{access}: {description}"
);
mmap.push(text);
if fi.derived_from.is_none() {
mmap.push(text);
coverage.all += 1;
if is_covered(&fi) {
coverage.covered += 1;
}
}
}
}
}
}
}
}

fn is_covered(f: &FieldInfo) -> bool {
!f.enumerated_values.is_empty() || f.write_constraint.is_some()
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -231,6 +278,12 @@ mod tests {
<description>Field 1</description>
<bitOffset>5</bitOffset>
<bitWidth>2</bitWidth>
<writeConstraint>
<range>
<minimum>0</minimum>
<maximum>0x3</maximum>
</range>
</writeConstraint>
</field>
<field>
<name>F2</name>
Expand Down Expand Up @@ -261,6 +314,27 @@ mod tests {
<name>REG1</name>
<addressOffset>0x10</addressOffset>
<description>Register B1</description>
<fields>
<field>
<name>F3</name>
<description>Field 3</description>
<bitOffset>10</bitOffset>
<bitWidth>1</bitWidth>
<enumeratedValues>
<name>EV_NAME</name>
<enumeratedValue>
<name>VAL1</name>
<description>Value description 1</description>
<value>0</value>
</enumeratedValue>
<enumeratedValue>
<name>VAL2</name>
<description>Value description 2</description>
<value>1</value>
</enumeratedValue>
</enumeratedValues>
</field>
</fields>
</register>
</registers>
</peripheral>
Expand All @@ -274,8 +348,10 @@ mod tests {
0x10000014 B REGISTER REG2: Register A2
0x10010000 A PERIPHERAL PeriphB
0x10010010 B REGISTER REG1: Register B1
0x10010010 C FIELD 10w01 F3: Field 3
INTERRUPT 001: INT_A1 (PeriphA): Interrupt A1
INTERRUPT 002: INT_B2 (PeriphB): Interrupt B2";
INTERRUPT 002: INT_B2 (PeriphB): Interrupt B2
Covered 2 from 3 fields.";

#[test]
fn mmap() {
Expand Down

0 comments on commit e5ab476

Please sign in to comment.