error: Cluster USART has no determinable `size` field
I get this error with ATSAMD21G18A.svd
I'm not opposed to rolling up my sleeves to help fix this if someone with context can tell me roughly what needs to happen. I'm a fast learner!
I see this with 631ab3e5ffaec4bb276d930b265a2a8178e7d82f
error: Cluster USART has no determinable `size` field
caused by: Warning! overlap while calculating Register Size within a Cluster! Cluster contents may be incorrectly aligned!
backtrace: stack backtrace:
0: 0x55bb5fecc8d4 - backtrace::backtrace::libunwind::trace::hbf9f65f12207138f
at /home/wez/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.5/src/backtrace/libunwind.rs:53
- backtrace::backtrace::trace::hd67ff4d2334f7ed6
at /home/wez/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.5/src/backtrace/mod.rs:42
1: 0x55bb5feca63c - backtrace::capture::Backtrace::new_unresolved::h642c5b6c9400d9d5
at /home/wez/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.5/src/capture.rs:88
2: 0x55bb5feca58e - backtrace::capture::Backtrace::new::h6b30f701e69e550b
at /home/wez/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.5/src/capture.rs:63
3: 0x55bb5fec76b6 - error_chain::make_backtrace::hc918c7599bfaea64
at /home/wez/.cargo/registry/src/github.com-1ecc6299db9ec823/error-chain-0.11.0/src/lib.rs:616
4: 0x55bb5fec772f - <error_chain::State as core::default::Default>::default::h548074ab69a8084d
at /home/wez/.cargo/registry/src/github.com-1ecc6299db9ec823/error-chain-0.11.0/src/lib.rs:710
5: 0x55bb5fde81bd - svd2rust::errors::Error::from_kind::hd36a5afffca28cb6
at /home/wez/github/svd2rust/<impl_error_chain_processed macros>:53
6: 0x55bb5fde83b9 - <svd2rust::errors::Error as core::convert::From<alloc::string::String>>::from::hd00d5407c74d1305
at src/errors.rs:1
7: 0x55bb5fd7ef70 - svd2rust::generate::peripheral::cluster_size_in_bits::ha74a72683196d068
at src/generate/peripheral.rs:210
8: 0x55bb5fe1a6ca - svd2rust::generate::peripheral::expand_cluster::{{closure}}::hbe5bc632c7386e96
at src/generate/peripheral.rs:246
9: 0x55bb5fd875dc - <core::result::Result<T, E>>::or_else::he8ffab4c771caf21
at /checkout/src/libcore/result.rs:691
10: 0x55bb5fd7f86d - svd2rust::generate::peripheral::expand_cluster::h447512a0d57fb8aa
at src/generate/peripheral.rs:243
11: 0x55bb5fd7e89f - svd2rust::generate::peripheral::expand::h8fc1592519c5606e
at src/generate/peripheral.rs:191
12: 0x55bb5fd7d6c8 - svd2rust::generate::peripheral::register_or_cluster_block::h682fffe6a6a9ec45
at src/generate/peripheral.rs:125
13: 0x55bb5fd7c792 - svd2rust::generate::peripheral::render::h008b4049f11701b1
at src/generate/peripheral.rs:78
14: 0x55bb5fde0b5f - svd2rust::generate::device::render::h25c68a216b631a00
at src/generate/device.rs:128
15: 0x55bb5fe25453 - svd2rust::run::hb3070a0e4fb05ceb
at src/main.rs:84
16: 0x55bb5fe25b86 - svd2rust::main::h76b2401efe189507
at src/main.rs:99
17: 0x55bb5fde9031 - std::rt::lang_start::{{closure}}::hf182223c25a0e056
at /checkout/src/libstd/rt.rs:74
18: 0x55bb60082ee7 - std::rt::lang_start_internal::{{closure}}::h6683f918b5e41df1
at libstd/rt.rs:59
- std::panicking::try::do_call::h9980f1b0ce760291
at libstd/panicking.rs:306
19: 0x55bb6008ca8e - __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:102
20: 0x55bb60083683 - std::panicking::try::h2b055bf317f9a3ac
at libstd/panicking.rs:285
- std::panic::catch_unwind::h8402e9b2ba9c09e5
at libstd/panic.rs:361
- std::rt::lang_start_internal::h591dc8f1c9bda6fc
at libstd/rt.rs:58
21: 0x55bb5fde9011 - std::rt::lang_start::hcbc8bede4be6939e
at /checkout/src/libstd/rt.rs:74
22: 0x55bb5fe2613d - main
23: 0x7f4a2898a1c0 - __libc_start_main
24: 0x55bb5fd7b4a9 - _start
25: 0x0 - <unknown>
I added more context to the warning:
caused by: Warning! overlap while calculating Register Size within a Cluster! Cluster contents may be incorrectly aligned! Single(
RegisterInfo {
name: "BAUD_FRAC_MODE",
description: "USART Baud Rate",
address_offset: 12,
size: Some(
16
),
access: None,
reset_value: None,
reset_mask: None,
fields: Some(
[
Field {
name: "BAUD",
description: Some(
"Baud Rate Value"
),
bit_range: BitRange {
offset: 0,
width: 13
},
access: None,
enumerated_values: [],
write_constraint: None,
_extensible: ()
},
Field {
name: "FP",
description: Some(
"Fractional Part"
),
bit_range: BitRange {
offset: 13,
width: 3
},
access: None,
enumerated_values: [],
write_constraint: None,
_extensible: ()
}
]
),
write_constraint: None,
_extensible: ()
}
)
Here's the offending sequence in the svd file:
<register>
<name>BAUD</name>
<description>USART Baud Rate</description>
<addressOffset>0x0C</addressOffset>
<size>16</size>
<fields>
<field>
<name>BAUD</name>
<description>Baud Rate Value</description>
<bitOffset>0</bitOffset>
<bitWidth>16</bitWidth>
</field>
</fields>
</register>
<register>
<name>BAUD_FRAC_MODE</name>
<description>USART Baud Rate</description>
<alternateRegister>BAUD</alternateRegister>
<addressOffset>0x0C</addressOffset>
<size>16</size>
<fields>
<field>
<name>BAUD</name>
<description>Baud Rate Value</description>
<bitOffset>0</bitOffset>
<bitWidth>13</bitWidth>
</field>
<field>
<name>FP</name>
<description>Fractional Part</description>
<bitOffset>13</bitOffset>
<bitWidth>3</bitWidth>
</field>
</fields>
</register>
May be another incarnation of https://github.com/japaric/svd2rust/issues/16 ?
I've hacked in some code to skip entries that have an alternateRegister, which seems to fit with the default disposition of #16 and probably fine (caveat: I haven't read any specs :-p)
I still had some more overlaps though, so I modified the code to skip entries that overlap:
diff --git a/src/generate/peripheral.rs b/src/generate/peripheral.rs
index 90df735..7480e3a 100644
--- a/src/generate/peripheral.rs
+++ b/src/generate/peripheral.rs
@@ -207,11 +207,16 @@ fn cluster_size_in_bits(info: &ClusterInfo, defs: &Defaults) -> Result<u32> {
for c in &info.children {
size += match *c {
Either::Left(ref reg) => {
- let pad = reg.address_offset.checked_sub(offset)
- .ok_or_else(||
- format!("Warning! overlap while calculating Register Size within a Cluster! Cluster contents may be incorrectly aligned!"))?
- * BITS_PER_BYTE;
-
+ if reg.alternate_register.is_some() {
+ 0
+ } else {
+ let pad = match reg.address_offset.checked_sub(offset) {
+ Some(size) => size * BITS_PER_BYTE,
+ None => {
+ eprintln!("Warning! overlap while calculating Register Size within a Cluster! Cluster contents may be incorrectly aligned! offset={} {:#?}", offset, reg);
+ continue;
+ }
+ };
let reg_size: u32 = expand_register(reg, defs, None)?
.iter()
@@ -219,6 +224,7 @@ fn cluster_size_in_bits(info: &ClusterInfo, defs: &Defaults) -> Result<u32> {
.sum();
pad + reg_size
+ }
}
Either::Right(ref clust) => {
let pad = clust.address_offset.checked_sub(offset)
Thinking about this a bit more, can we simplify this?
If addressOffset is the start of the range of bits for the register (relative to its container; the cluster) and we can compute the bit width of a group, then we know the end of the range of bits for each of those registers.
The size is therefore the maximum end position for all of its children.
Am I missing something there?
/// Recursively calculate the size of a cluster. A cluster's size is the maximum
/// end position of its recursive children.
fn cluster_size_in_bits(info: &ClusterInfo, defs: &Defaults) -> Result<u32> {
let mut size = 0;
for c in &info.children {
let end = match *c {
Either::Left(ref reg) => {
let reg_size: u32 = expand_register(reg, defs, None)?
.iter()
.map(|rbf| rbf.size)
.sum();
(reg.address_offset * BITS_PER_BYTE) + reg_size
}
Either::Right(ref clust) => {
(clust.address_offset * BITS_PER_BYTE) + cluster_size_in_bits(clust, defs)?
}
};
size = size.max(end);
}
Ok(size)
}
Hey @wez, contributions are welcome :) I'll try and take a look at this issue (and your solutions) this evening.
@wez @jamesmunns Did you already solve this? I also ran into this issue with a newer SVD file for the same chip from Atmel ATSAMD21G18AU.svd
I tried with the current master (fb54754c2470327788778e7673eac9dfaf5a6765) but still got this error.
@bachp I have WIP here: https://github.com/wez/atsamd21-rs
There are a couple of issues with the code gen that block my patches from being merged, and I hope to find time to address those in the coming week
The cluster/union stuff has now been merged into master. The samd21 SVDs have one known issue remaining with derivedFrom that causes the GPIO pin configuration and mux registers not to be generated correctly. https://github.com/japaric/svd2rust/pull/193 is open for that