Skip to content

Suggestion: Traits for converting from/to raw types #107

@thelenlucas

Description

@thelenlucas

Currently, reasoning about bitfields in the general sense is rather difficult, because the functions they provide are unique. This is usually quite advantageous, as that lets them be const without much effort. However, under some circumstances it would make sense to be able to reason about converting between bitfields and their raw types without extra manual boilerplate.

Consider an MMIO-banked peripheral, for which that peripheral's banked location may vary between hardware platforms, but has a single API, with a series of registers offset from it's base location.

trait Peripheral {
    const BASE: usize;
}

It would be nice to be able to have a trait RawBitfield or similar that could provide more generic conversion functions such that I could do:

trait Peripheral {
    const BASE: usize;
}

trait RawBitfield {
    type Raw: Sized;

    fn from_raw(raw: Self::Raw) -> Self;

    fn into_raw(self) -> Self::Raw;
}

trait Register: RawBitfield {
    const OFFSET: usize;
}

trait ReadRegister<Reg: Register>: Peripheral {
    fn read(&self) -> Reg {
        unsafe {
            let reg = (Self::BASE + Reg::OFFSET) as *const Reg::Raw;

            Reg::from_raw(core::ptr::read_volatile(reg))
        }
    }
}

trait WriteRegister<Reg: Register>: Peripheral {
    fn write(&mut self, reg: Reg) {
        unsafe {
            let addr = (Self::BASE + Reg::OFFSET) as *mut Reg::Raw;
            addr.write_volatile(reg.into_raw());
        }
    }
}

This would open up some interesting possibilities for writing MMIO devices, at the very least, and as a HAL/PAC author, especially as one for a subset of devices without available SVD descriptors, one I would make much use of.

It would probably be worth gating this on a macro parameter, or even a feature flag, to avoid nuking the trait solver on large projects.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions