Derive Macro volatile_macro::VolatileFieldAccess
source · #[derive(VolatileFieldAccess)]
{
// Attributes available to this derive:
#[access]
}
Expand description
A derive macro for method-based accesses to volatile structures.
This macro allows you to access the fields of a volatile structure via methods that enforce access limitations.
It is also more easily chainable than map_field
.
This macro generates and implements a new {T}VolatileFieldAccess
trait, that you have to import if used from other modules.
Currently, the trait is only implemented for VolatilePtr<'_, _, ReadWrite>
.
§Examples
use volatile::access::ReadOnly;
use volatile::{VolatileFieldAccess, VolatileRef};
#[repr(C)]
#[derive(VolatileFieldAccess, Default)]
pub struct DeviceConfig {
feature_select: u32,
#[access(ReadOnly)]
feature: u32,
}
let mut device_config = DeviceConfig::default();
let mut volatile_ref = VolatileRef::from_mut_ref(&mut device_config);
let volatile_ptr = volatile_ref.as_mut_ptr();
volatile_ptr.feature_select().write(42);
assert_eq!(volatile_ptr.feature_select().read(), 42);
// This does not compile, because we specified `#[access(ReadOnly)]` for this field.
// volatile_ptr.feature().write(42);
// A real device might have changed the value, though.
assert_eq!(volatile_ptr.feature().read(), 0);
// You can also use shared references.
let volatile_ptr = volatile_ref.as_ptr();
assert_eq!(volatile_ptr.feature_select().read(), 42);
// This does not compile, because `volatile_ptr` is `ReadOnly`.
// volatile_ptr.feature_select().write(42);
§Details
This macro generates a new trait ({T}VolatileFieldAccess
) and implements it for VolatilePtr<'a, T, ReadWrite>
.
The example above results in (roughly) the following code:
use volatile::access::{ReadOnly, ReadWrite, RestrictAccess};
use volatile::{map_field, VolatilePtr};
pub trait DeviceConfigVolatileFieldAccess<'a, A> {
fn feature_select(self) -> VolatilePtr<'a, u32, A::Restricted>
where
A: RestrictAccess<ReadWrite>;
fn feature(self) -> VolatilePtr<'a, u32, A::Restricted>
where
A: RestrictAccess<ReadOnly>;
}
impl<'a, A> DeviceConfigVolatileFieldAccess<'a, A> for VolatilePtr<'a, DeviceConfig, A> {
fn feature_select(self) -> VolatilePtr<'a, u32, A::Restricted>
where
A: RestrictAccess<ReadWrite>
{
map_field!(self.feature_select).restrict()
}
fn feature(self) -> VolatilePtr<'a, u32, A::Restricted>
where
A: RestrictAccess<ReadOnly>
{
map_field!(self.feature).restrict()
}
}