svd2rust icon indicating copy to clipboard operation
svd2rust copied to clipboard

Alignment padding in generated structs is incorrectly accounted for.

Open rcls opened this issue 4 years ago • 2 comments

svd2rust accounts for alignment padding incorrectly.

E.g., in the attached example, struct ALIGNME has 6 bytes of data and 2 bytes of alignment padding, a total of 8 bytes. The following field next32 at offset 8 therefore needs no explicit padding added before it.

But svd2rust has not counted the alignment padding and ends up inserting 2 bytes of incorrect padding. After further alignment, this appears to leave next32 at offset 12 instead of the correct 8.

.svd and part of the output .rs inline below. Github wouldn't let me add them as attachments.....

#[repr(C)]
pub struct RegisterBlock {
    #[doc = "0x00 - u32+u16"]
    pub alignme: ALIGNME,
    _reserved1: [u8; 2usize],
    #[doc = "0x08 - Following 32 bit field"]
    pub next32: crate::Reg<next32::NEXT32_SPEC>,
}
#[repr(C)]
pub struct ALIGNME {
    #[doc = "0x00 - Thirty two and serious"]
    pub reg32: crate::Reg<self::alignme::reg32::REG32_SPEC>,
    #[doc = "0x04 - 16 bit reigster"]
    pub reg16: crate::Reg<self::alignme::reg16::REG16_SPEC>,
}

and the SVD

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator version: 1.6.0.225 -->
<device schemaVersion="1.3" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd">
  <vendor>Testing 123</vendor>
  <vendorID>NotReal</vendorID>
  <name>dummy</name>
  <series>dumb</series>
  <version>1.0</version>
  <description>dummy</description>
  <licenseText>Made up example license.</licenseText>
  <cpu>
    <name>CM4</name>
    <revision>r0p1</revision>
    <endian>little</endian>
    <mpuPresent>true</mpuPresent>
    <fpuPresent>true</fpuPresent>
    <vtorPresent>1</vtorPresent>
    <nvicPrioBits>3</nvicPrioBits>
    <vendorSystickConfig>0</vendorSystickConfig>
  </cpu>
  <addressUnitBits>8</addressUnitBits>
  <width>32</width>
  <resetValue>0x00000000</resetValue>
  <resetMask>0xFFFFFFFF</resetMask>
  <peripherals>
    <peripheral>
      <name>PERI</name>
      <description>A peripheral</description>
      <baseAddress>0x40000000</baseAddress>
      <addressBlock>
        <offset>0</offset>
        <size>4096</size>
        <usage>registers</usage>
      </addressBlock>
      <registers>
        <cluster>
          <name>alignme</name>
          <description>u32+u16</description>
          <addressOffset>0x00000000</addressOffset>
          <register>
            <name>REG32</name>
            <description>Thirty two and serious</description>
            <addressOffset>0x0</addressOffset>
            <size>32</size>
            <access>read-write</access>
            <resetValue>0x0</resetValue>
            <resetMask>0x0</resetMask>
            <fields>
              <field>
                <name>F32</name>
                <description>A 32 bit field.</description>
                <bitRange>[31:0]</bitRange>
                <access>read-write</access>
              </field>
            </fields>
          </register>
          <register>
            <name>REG16</name>
            <description>16 bit reigster</description>
            <addressOffset>0x4</addressOffset>
            <size>16</size>
            <access>read-write</access>
            <resetValue>0x0</resetValue>
            <resetMask>0x0</resetMask>
            <fields>
              <field>
                <name>F16</name>
                <description>A 16 bit field.  Sweet 16.</description>
                <bitRange>[15:0]</bitRange>
                <access>read-write</access>
              </field>
            </fields>
          </register>
        </cluster>
        <register>
          <name>NEXT32</name>
          <description>Following 32 bit field</description>
          <addressOffset>8</addressOffset>
          <size>32</size>
          <access>read-write</access>
          <resetValue>0</resetValue>
          <resetMask>0</resetMask>
          <fields>
            <field>
              <name>F32</name>
              <description>32 bits again</description>
              <bitRange>[31:0]</bitRange>
              <access>read-write</access>
            </field>
          </fields>
        </register>
      </registers>
    </peripheral>
  </peripherals>
</device>


rcls avatar May 11 '21 09:05 rcls

I have no idea if this is a real-life issue, or if SVD has rules that say this shouldn't happen.

rcls avatar May 11 '21 09:05 rcls

Have anyone given this any thought? this could be resolved by using packed repr rather then C but not sure if thats the right solution

theli-ua avatar Aug 31 '21 00:08 theli-ua