Skip to content

Be more careful computing the size of an array Cluster. #519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- MSP430 API for atomically changing register bits, gated behind the `--nightly` flag
- New SVD test for `msp430fr2355`

### Added

- Option `-o`(`--output-path`) let you specify output directory path

### Changed

- `_rererved` fields in `RegisterBlock` now hexidemical usize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) My mistake

- options can be set now with `svd2rust.toml` config
- option `ignore_groups` for optional disabling #506
- [breaking-change] move `const_generic` from features to options
- use `Config` to pass options over all render levels
- Use register iterator from `svd-parser`
- rm unneeded `core::convert::` prefix on `From`

### Fixed

- Padding has been corrected for SVD files containing nested array clusters.

This showed up on Cypress PSOC and Traveo II CPUs.

## [v0.18.0] - 2021-04-17

### Added
Expand Down
54 changes: 44 additions & 10 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ fn register_or_cluster_block(
let pad = region.offset - last_end;
if pad != 0 {
let name = Ident::new(&format!("_reserved{}", i), span);
let pad = pad as usize;
let pad = util::hex(pad as u64);
rbfs.extend(quote! {
#name : [u8; #pad],
});
Expand All @@ -478,11 +478,20 @@ fn register_or_cluster_block(
let is_region_a_union = region.is_union();

for reg_block_field in &region.rbfs {
let comment = &format!(
"0x{:02x} - {}",
reg_block_field.offset,
util::escape_brackets(util::respace(&reg_block_field.description).as_ref()),
)[..];
let comment = if reg_block_field.size > 32 {
format!(
"0x{:02x}..0x{:02x} - {}",
reg_block_field.offset,
reg_block_field.offset + reg_block_field.size / 8,
util::escape_brackets(util::respace(&reg_block_field.description).as_ref()),
)
} else {
format!(
"0x{:02x} - {}",
reg_block_field.offset,
util::escape_brackets(util::respace(&reg_block_field.description).as_ref()),
)
};

if is_region_a_union {
let name = &reg_block_field.field.ident;
Expand Down Expand Up @@ -533,7 +542,7 @@ fn register_or_cluster_block(
),
span,
);
let pad = (region.end - region.offset) as usize;
let pad = util::hex((region.end - region.offset) as u64);
rbfs.extend(quote! {
#name: [u8; #pad],
})
Expand Down Expand Up @@ -592,9 +601,34 @@ fn expand(
Ok(ercs_expanded)
}

/// Recursively calculate the size of a cluster. A cluster's size is the maximum
/// end position of its recursive children.
/// Calculate the size of a Cluster. If it is an array, then the dimensions
/// tell us the size of the array. Otherwise, inspect the contents using
/// [cluster_info_size_in_bits].
fn cluster_size_in_bits(
cluster: &Cluster,
defs: &RegisterProperties,
config: &Config,
) -> Result<u32> {
match cluster {
Cluster::Single(info) => cluster_info_size_in_bits(info, defs, config),
// If the contained array cluster has a mismatch between the
// dimIncrement and the size of the array items, then the array
// will get expanded in expand_cluster below. The overall size
// then ends at the last array entry.
Cluster::Array(info, dim) => {
if dim.dim == 0 {
return Ok(0); // Special case!
}
let last_offset = (dim.dim - 1) * dim.dim_increment * BITS_PER_BYTE;
let last_size = cluster_info_size_in_bits(info, defs, config);
Ok(last_offset + last_size?)
}
}
}

/// Recursively calculate the size of a ClusterInfo. A cluster's size is the
/// maximum end position of its recursive children.
fn cluster_info_size_in_bits(
info: &ClusterInfo,
defs: &RegisterProperties,
config: &Config,
Expand Down Expand Up @@ -632,7 +666,7 @@ fn expand_cluster(

let defs = cluster.default_register_properties.derive_from(defs);

let cluster_size = cluster_size_in_bits(cluster, &defs, config)
let cluster_size = cluster_info_size_in_bits(cluster, &defs, config)
.with_context(|| format!("Cluster {} has no determinable `size` field", cluster.name))?;

match cluster {
Expand Down