rust-embedded / svd2rust

Generate Rust register maps (`struct`s) from SVD files
Apache License 2.0
687 stars 149 forks source link

Is ArrayProxy still usefull? #635

Closed burrbull closed 2 years ago

burrbull commented 2 years ago

After #579 merged most cases of ArrayProxy are covered by ordinary arrays. Is there SVDs which still use it?

burrbull commented 2 years ago

cc @rcls @duskmoon314

duskmoon314 commented 2 years ago

I use ArrayProxy in d1-pac for D1-H's MSGBOX.

In d1_unofficial.svd, I describe the msgbox in the following way according to the reference:

<peripheral>
  <name>DSP_MSGBOX</name>
  <description>DSP Message Box</description>
  <groupName>System</groupName>
  <baseAddress>0x01701000</baseAddress>
  <registers>
    <cluster>
      <dim>2</dim>
      <dimIncrement>0x100</dimIncrement>
      <name>msgbox%s</name>
      <description>Communicate with CPU[N]</description>
      <addressOffset>0x0</addressOffset>
      <register>...

That is, there are two sets of 9 registers with the same function.

The generated code is (with ArrayProxy / without):

image

I haven't used this in my project yet, and I think it is somehow just a preference. For me, they are both fine. Thus I have no objections.

burrbull commented 2 years ago

Clusters with holes. I see. But why reserved is absent on the left? What size_of of this ArrayProxy?

duskmoon314 commented 2 years ago

But why reserved is absent on the left?

I think is because ArrayProxy's stride is 0x100. And actually only 0x90 is used.

What size_of of this ArrayProxy?

Do you mean std::mem::size_of? The result is as below.

0    size_of::<d1_pac::dsp_msgbox::RegisterBlock>()
144  size_of::<d1_pac::dsp_msgbox::MSGBOX>()
0    size_of::<d1_pac::ArrayProxy<d1_pac::dsp_msgbox::MSGBOX, 2, 0x0100>>()
burrbull commented 2 years ago

If it is zero sized then we need to add _reserved after it for correct align of followed fields of RegisterBlock. Looks like a bug for me.

burrbull commented 2 years ago

Could you add more registers in this peripheral and compare again?

duskmoon314 commented 2 years ago

I add an register with the name after_cluster just after the cluster part:

<registers>
  <cluster>
  ...
  </cluster>
  <register>
    <name>after_cluster</name>
    <addressOffset>0x200</addressOffset>
  </register>
</registers>

Then the generated RegisterBlock is:

#[doc = r"Register block"]
#[repr(C)]
pub struct RegisterBlock {
    #[doc = "0x00 - Communicate with CPU\\[N\\]"]
    pub msgbox: crate::ArrayProxy<MSGBOX, 2, 0x0100>,
    _reserved1: [u8; 0x0200],
    #[doc = "0x200 - "]
    pub after_cluster: crate::Reg<after_cluster::AFTER_CLUSTER_SPEC>,
}

And the result of size_of is:

516  size_of::<d1_pac::dsp_msgbox::RegisterBlock>()
144  size_of::<d1_pac::dsp_msgbox::MSGBOX>()
0    size_of::<d1_pac::ArrayProxy<d1_pac::dsp_msgbox::MSGBOX, 2, 0x0100>>()
burrbull commented 2 years ago

Looks good. Thanks