You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
592: add code generation support of peripheral arrays r=burrbull a=duskmoon314
## Brief Intro
- generate ArrayProxy of peripherals when const_generic is true
- generate separate struct of peripherals when const_generic is false
close issue: #492
## Design
**Notice:** This is my first try of implement this feature. Please provide suggestions for this PR to better implement this feature.
This PR aims to achieve what issue #492 is asking for. This PR implements a basic try of generating codes depending on the `const_generic` flag.
Let's say we have an svd file with descriptions of peripherals like this:
```XML
<peripheral>
<dim>2</dim>
<dimIncrement>0x100</dimIncrement>
<name>PTEST[%s]</name>
<groupName>PGroup</groupName>
<baseAddress>0x20000000</baseAddress>
<addressBlock>
<offset>0</offset>
<size>0x100</size>
<usage>registers</usage>
</addressBlock>
<registers>
...
</registers>
</peripheral>
```
If the `const_generic` is `false`, there is no `ArrayProxy`. So I generate separate structs and only one mod:
```rust
pub struct PTEST0 {
_marker: PhantomData<*const ()>,
}
...
impl PTEST0 {
#[doc = r"Pointer to the register block"]
pub const PTR: *const ptest::RegisterBlock = 0x2000_0000 as *const _;
...
}
impl Deref for PTEST0 {
type Target = ptest::RegisterBlock;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*Self::PTR }
}
}
pub struct PTEST1 {
_marker: PhantomData<*const ()>,
}
...
impl PTEST1 {
#[doc = r"Pointer to the register block"]
pub const PTR: *const ptest::RegisterBlock = 0x2000_0100 as *const _;
...
}
impl Deref for PTEST1 {
type Target = ptest::RegisterBlock;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*Self::PTR }
}
}
#[doc = "PTEST"]
pub mod ptest;
```
**NOTICE:** The following design is actually incorrect and has been removed. See the following comment.
<details>
If the `const_generic` is `true`, we can use `ArrayProxy`. So I generate code like this:
```rust
pub struct PTEST {
_marker: PhantomData<*const ()>,
}
...
pub struct Peripherals {
#[doc = "PTEST"]
pub PTEST: crate::ArrayProxy<PTEST, 2usize, 0x0100>,
...
impl Peripherals {
...
pub unsafe fn steal() -> Self {
DEVICE_PERIPHERALS = true;
Peripherals {
PTEST: crate::ArrayProxy::new(),
```
Since `_array` is a private field of `ArrayProxy`, I add a `new` method to implement the `steal` method of `Peripherals`.
</details>
I also add the support of using `name_of` on `MaybeArray<PeripheralInfo>` to achieve this implementation.
Well, I haven't fully tested this implementation yet. So there may be problems that need to be solved.
Co-authored-by: Campbell He <campbell.he@icloud.com>
Co-authored-by: Campbell He <duskmoon314@users.noreply.github.com>
0 commit comments