Struct volatile_ptr::Volatile
[−]
[src]
pub struct Volatile<T: ?Sized>(_);
A volatile pointer.
This type acts as a pointer that only uses volatile operations. Pointer arithmetic can be performed on it, and it can be dereferenced to its raw type in order to perform volatile memory operations. This is especially useful for I/O operations where writing and reading from memory mapped I/O registers would normally be optimized out by the compiler.
The Volatile
type has the same syntax as a primitive pointer, so all functions that you can
expect to use with a primitive pointer like *const
or *mut
can also be used with a
Volatile
pointer.
Examples
use volatile::Volatile; let value: i32 = 0; unsafe { let mut ptr = Volatile::new(&value); let mask = 0x0F0F; *ptr |= mask; } assert_eq!(value, 0x0F0F);
Volatile
pointers can also be used to point at whole structs, and any memory accesses into
that struct will also be considered volatile
use volatile::Volatile; use std::mem; struct IODevice { reg1: u32, reg2: u32, reg3: u32, } let io_device: IODevice = unsafe { mem::uninitialized() }; unsafe { let mut ptr = Volatile::new(&io_device); ptr.reg1 = 1; ptr.reg2 = 2; ptr.reg3 = 3; assert_eq!(ptr.reg1, 1); assert_eq!(ptr.reg2, 2); assert_eq!(ptr.reg3, 3); }
Safety
Because Volatile
pointers are often used for memory mapped peripherals, the compiler can not
guarantee that the address pointed at is valid, so the creation of a Volatile
pointer is
unsafe. If you have a valid reference to some object, you can safely create a Volatile
pointer to that object through the From
trait implemented for references.
use volatile::Volatile; let x: u32 = 0; let ptr = Volatile::from(&x);
Be wary however that a Volatile
pointer provides interior mutability, so creating a pointer
from a shared reference may break immutability guarantees if used improperly.
Methods
impl<T: ?Sized> Volatile<T>
[src]
unsafe fn new(ptr: *const T) -> Self
Create a new Volatile
pointer.
Examples
use volatile::Volatile; const IO_ADDR: *const u32 = 0x4100_2000 as *const _; unsafe { let ptr = Volatile::new(IO_ADDR); }
Safety
Because Volatile
pointers are often used to point at essentially arbitrary memory
addresses, the compiler can not guarantee that the pointed at address is valid, so the
creation of a Volatile
pointer is considered unsafe.
fn is_null(self) -> bool where
T: Sized,
T: Sized,
Return true if the pointer is null, false otherwise
fn as_ptr(self) -> *const T
Return the inner pointer.
Future accesses to this inner pointer will not be volatile.
fn as_mut(self) -> *mut T
Returns the inner pointer mutably.
Future accesses to this inner pointer will not be volatile.
unsafe fn offset(self, count: isize) -> Self where
T: Sized,
T: Sized,
Calculate the offset from the inner pointer, returning a new Volatile pointer.
count
is in units of T; e.g. a count
of 3 represents a pointer offset of 3 * size_of::<T>()
bytes.
Safety
Both the starting and resulting pointer must be either in bounds or one byte past the end of an allocated object. If either pointer is out of bounds or arithmetic overflow occurs then any further use of the returned value will result in undefined behavior.
unsafe fn store(&mut self, rhs: T) where
T: Sized,
T: Sized,
Store a value into the memory address pointed at.
This operation is guaranteed to not be optimized out by the compiler, even if it believes that it will have no effect on the program.
Examples
use volatile::Volatile; let x: u32 = 0; unsafe { let mut ptr = Volatile::new(&x); ptr.store(0x1234); } assert_eq!(x, 0x1234);
Safety
Storing to a Volatile
pointer is equivalent to storing a value to a primitive raw pointer
so the operation could potentially be performed on some shared data or even an invalid
address.
unsafe fn load(&self) -> T where
T: Sized,
T: Sized,
Load a value from the memory address pointed at.
This operation is guaranteed to not be optimized out by the compiler, even if it believes that it will have no effect on the program.
Examples
use volatile::Volatile; let x: u32 = 0xAAAA; unsafe { let ptr = Volatile::new(&x); assert_eq!(ptr.load(), 0xAAAA); }
Safety
Loading from a Volatile
pointer is equivalent to loading a value from a primitive raw
pointer so the operation could potentially be performed on an invalid address.
unsafe fn modify<F>(&mut self, f: F) where
T: Sized,
F: FnOnce(&mut T),
T: Sized,
F: FnOnce(&mut T),
Perform a read-modify-write operation on the memory address pointed at.
This operation is guaranteed to not be optimized out by the compiler, even if it believes that it will have no effect on the program. The value stored in the address pointed at will be loaded and passed into the given function before being written back out to memory.
Examples
use volatile::Volatile; let x: u32 = 0; unsafe { let mut ptr = Volatile::new(&x); ptr.modify(|x| { let old = *x; if old == 0 { *x = 100; } else { *x = 200; } }); } assert_eq!(x, 100);
Safety
Modifying a Volatile
pointer's contents involves both a load and store of the underlying
raw pointer so it could be performed on some shared data or even on an invalid address.
Trait Implementations
impl<T: Copy + ?Sized> Copy for Volatile<T>
[src]
impl<T: Clone + ?Sized> Clone for Volatile<T>
[src]
fn clone(&self) -> Volatile<T>
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0
Performs copy-assignment from source
. Read more
impl<T: PartialEq + ?Sized> PartialEq for Volatile<T>
[src]
fn eq(&self, __arg_0: &Volatile<T>) -> bool
This method tests for self
and other
values to be equal, and is used by ==
. Read more
fn ne(&self, __arg_0: &Volatile<T>) -> bool
This method tests for !=
.
impl<T: Eq + ?Sized> Eq for Volatile<T>
[src]
impl<T: PartialOrd + ?Sized> PartialOrd for Volatile<T>
[src]
fn partial_cmp(&self, __arg_0: &Volatile<T>) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
fn lt(&self, __arg_0: &Volatile<T>) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
fn le(&self, __arg_0: &Volatile<T>) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
fn gt(&self, __arg_0: &Volatile<T>) -> bool
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
fn ge(&self, __arg_0: &Volatile<T>) -> bool
This method tests greater than or equal to (for self
and other
) and is used by the >=
operator. Read more
impl<T: Ord + ?Sized> Ord for Volatile<T>
[src]
fn cmp(&self, __arg_0: &Volatile<T>) -> Ordering
This method returns an Ordering
between self
and other
. Read more
impl<T: Debug + ?Sized> Debug for Volatile<T>
[src]
impl<'a, T: ?Sized + 'a> From<&'a T> for Volatile<T>
[src]
fn from(reference: &'a T) -> Self
Performs the conversion.
impl<'a, T: ?Sized + 'a> From<&'a mut T> for Volatile<T>
[src]
fn from(reference: &'a mut T) -> Self
Performs the conversion.
impl<T: ?Sized> Deref for Volatile<T>
[src]
type Target = T
The resulting type after dereferencing
fn deref(&self) -> &Self::Target
The method called to dereference a value
impl<T: ?Sized> DerefMut for Volatile<T>
[src]
impl<T: ?Sized> Hash for Volatile<T> where
T: Sized,
[src]
T: Sized,
fn hash<H: Hasher>(&self, state: &mut H)
Feeds this value into the given [Hasher
]. Read more
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0
H: Hasher,
Feeds a slice of this type into the given [Hasher
]. Read more