Skip to content

Commit b8d3f7d

Browse files
committed
per-peripheral field coverage
1 parent e5ab476 commit b8d3f7d

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

src/mmap/mmap_cli.rs

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ struct CoveredFields {
1212
covered: u32,
1313
}
1414

15+
impl core::ops::Add for CoveredFields {
16+
type Output = Self;
17+
fn add(self, rhs: Self) -> Self::Output {
18+
Self {
19+
all: self.all + rhs.all,
20+
covered: self.covered + rhs.covered,
21+
}
22+
}
23+
}
24+
25+
impl core::ops::AddAssign for CoveredFields {
26+
fn add_assign(&mut self, rhs: Self) {
27+
*self = *self + rhs
28+
}
29+
}
30+
1531
/// Output sorted text of every peripheral, register, field, and interrupt
1632
/// in the device, such that automated diffing is possible.
1733
pub fn parse_device(svd_file: &Path) -> Result<()> {
@@ -34,47 +50,50 @@ fn get_text<R: Read>(svd: &mut R) -> Result<String> {
3450
}
3551

3652
fn to_text(peripherals: &[Peripheral]) -> String {
37-
let mut mmap: Vec<String> = vec![];
53+
let mut mmap = Vec::new();
3854
let mut coverage = CoveredFields::default();
3955

4056
for p in peripherals {
4157
match p {
4258
Peripheral::Single(p) => {
43-
get_peripheral(p, &mut mmap);
44-
get_interrupts(p, &mut mmap);
59+
let mut pcov = CoveredFields::default();
4560
let registers = get_periph_registers(p, peripherals);
61+
let mut rmmap = Vec::new();
4662
get_registers(
4763
p.base_address,
4864
registers.as_ref(),
4965
"",
50-
&mut mmap,
51-
&mut coverage,
66+
&mut rmmap,
67+
&mut pcov,
5268
);
69+
get_peripheral(p, &mut mmap, pcov);
70+
get_interrupts(p, &mut mmap);
71+
mmap.extend(rmmap);
72+
coverage += pcov;
5373
}
5474
Peripheral::Array(p, d) => {
75+
let mut pcov = CoveredFields::default();
5576
for pi in svd::peripheral::expand(p, d) {
56-
get_peripheral(&pi, &mut mmap);
57-
get_interrupts(&pi, &mut mmap);
5877
let registers = get_periph_registers(&pi, peripherals);
78+
let mut rmmap = Vec::new();
5979
get_registers(
6080
pi.base_address,
6181
registers.as_ref(),
6282
"",
63-
&mut mmap,
64-
&mut coverage,
83+
&mut rmmap,
84+
&mut pcov,
6585
);
86+
get_peripheral(&pi, &mut mmap, pcov);
87+
get_interrupts(&pi, &mut mmap);
88+
mmap.extend(rmmap);
89+
coverage += pcov;
6690
}
6791
}
6892
}
6993
}
7094

7195
mmap.sort();
72-
let mut mmap = mmap.join("\n");
73-
mmap.push_str(&format!(
74-
"\nCovered {} from {} fields.",
75-
coverage.covered, coverage.all
76-
));
77-
mmap
96+
mmap.join("\n")
7897
}
7998

8099
fn get_periph_registers<'a>(
@@ -96,11 +115,13 @@ fn get_periph_registers<'a>(
96115
}
97116
}
98117

99-
fn get_peripheral(peripheral: &PeripheralInfo, mmap: &mut Vec<String>) {
118+
fn get_peripheral(peripheral: &PeripheralInfo, mmap: &mut Vec<String>, coverage: CoveredFields) {
100119
let text = format!(
101-
"{} A PERIPHERAL {}",
120+
"{} A PERIPHERAL {} ({}/{} fields covered)",
102121
str_utils::format_address(peripheral.base_address),
103-
peripheral.name
122+
peripheral.name,
123+
coverage.covered,
124+
coverage.all,
104125
);
105126
mmap.push(text);
106127
}
@@ -135,6 +156,7 @@ fn get_registers(
135156
for r in registers {
136157
match &r {
137158
RegisterCluster::Register(r) => {
159+
let mut rcov = CoveredFields::default();
138160
let access = svd_utils::access_with_brace(r.properties.access);
139161
let derived = derived_str(&r.derived_from);
140162
match r {
@@ -147,7 +169,7 @@ fn get_registers(
147169
"{addr} B REGISTER {rname}{derived}{access}: {description}"
148170
);
149171
mmap.push(text);
150-
get_fields(r, &addr, mmap, coverage);
172+
get_fields(r, &addr, mmap, &mut rcov);
151173
}
152174
Register::Array(r, d) => {
153175
for ri in svd::register::expand(r, d) {
@@ -160,10 +182,11 @@ fn get_registers(
160182
"{addr} B REGISTER {rname}{derived}{access}: {description}"
161183
);
162184
mmap.push(text);
163-
get_fields(&ri, &addr, mmap, coverage);
185+
get_fields(&ri, &addr, mmap, &mut rcov);
164186
}
165187
}
166188
}
189+
*coverage += rcov;
167190
}
168191
RegisterCluster::Cluster(c) => {
169192
let derived = derived_str(&c.derived_from);
@@ -341,17 +364,16 @@ mod tests {
341364
</peripherals>
342365
</device>";
343366

344-
static EXPECTED_MMAP: &str = r"0x10000000 A PERIPHERAL PeriphA
367+
static EXPECTED_MMAP: &str = r"0x10000000 A PERIPHERAL PeriphA (1/2 fields covered)
345368
0x10000010 B REGISTER REG1: Register A1
346369
0x10000010 C FIELD 05w02 F1: Field 1
347370
0x10000010 C FIELD 10w01 F2: Field 2
348371
0x10000014 B REGISTER REG2: Register A2
349-
0x10010000 A PERIPHERAL PeriphB
372+
0x10010000 A PERIPHERAL PeriphB (1/1 fields covered)
350373
0x10010010 B REGISTER REG1: Register B1
351374
0x10010010 C FIELD 10w01 F3: Field 3
352375
INTERRUPT 001: INT_A1 (PeriphA): Interrupt A1
353-
INTERRUPT 002: INT_B2 (PeriphB): Interrupt B2
354-
Covered 2 from 3 fields.";
376+
INTERRUPT 002: INT_B2 (PeriphB): Interrupt B2";
355377

356378
#[test]
357379
fn mmap() {

0 commit comments

Comments
 (0)