Skip to content

Commit 8be4430

Browse files
committed
Update documentation
1 parent 93fb1e1 commit 8be4430

File tree

1 file changed

+50
-65
lines changed

1 file changed

+50
-65
lines changed

src/lib.rs

Lines changed: 50 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
11
#![cfg_attr(feature = "const_fn", feature(const_fn))]
22

3-
//! Provides wrapper types `Volatile`, `ReadOnly`, `WriteOnly`, `ReadWrite`, which wrap any copy-able type and allows for
4-
//! volatile memory access to wrapped value. Volatile memory accesses are never optimized away by
5-
//! the compiler, and are useful in many low-level systems programming and concurrent contexts.
3+
//! Provides the wrapper type `Volatile`, which wraps a reference to any copy-able type and allows
4+
//! for volatile memory access to wrapped value. Volatile memory accesses are never optimized away
5+
//! by the compiler, and are useful in many low-level systems programming and concurrent contexts.
66
//!
77
//! The wrapper types *do not* enforce any atomicity guarantees; to also get atomicity, consider
88
//! looking at the `Atomic` wrapper type found in `libcore` or `libstd`.
99
//!
1010
//! These wrappers do not depend on the standard library and never panic.
11-
//!
12-
//! # Dealing with Volatile Pointers
13-
//!
14-
//! Frequently, one may have to deal with volatile pointers, eg, writes to specific memory
15-
//! locations. The canonical way to solve this is to cast the pointer to a volatile wrapper
16-
//! directly, eg:
17-
//!
18-
//! ```rust
19-
//! use volatile::Volatile;
20-
//!
21-
//! let mut_ptr = 0xFEE00000 as *mut u32;
22-
//!
23-
//! let volatile_ptr = mut_ptr as *mut Volatile<u32>;
24-
//! ```
25-
//!
26-
//! and then perform operations on the pointer as usual in a volatile way. This method works as all
27-
//! of the volatile wrapper types are the same size as their contained values.
11+
2812
#![no_std]
2913

3014
pub use crate::access::{ReadWrite, Readable, Writable};
@@ -37,11 +21,14 @@ use core::{
3721

3822
mod access;
3923

40-
/// A wrapper type around a volatile variable, which allows for volatile reads and writes
41-
/// to the contained value. The stored type needs to be `Copy`, as volatile reads and writes
42-
/// take and return copies of the value.
24+
/// A wrapper type around a reference to a volatile variable.
25+
///
26+
/// Allows volatile reads and writes on the referenced value. The referenced value needs to
27+
/// be `Copy`, as volatile reads and writes take and return copies of the value.
4328
///
4429
/// The size of this struct is the same as the size of the contained type.
30+
///
31+
/// TODO: read/write permissions
4532
#[derive(Debug, Default, Clone)]
4633
#[repr(transparent)]
4734
pub struct Volatile<T, A = ReadWrite> {
@@ -50,17 +37,18 @@ pub struct Volatile<T, A = ReadWrite> {
5037
}
5138

5239
impl<T> Volatile<T> {
53-
/// Construct a new volatile instance wrapping the given value.
40+
/// Construct a new volatile instance wrapping the given value reference.
41+
///
42+
/// ## Example
5443
///
5544
/// ```rust
5645
/// use volatile::Volatile;
5746
///
58-
/// let value = Volatile::new(0u32);
59-
/// ```
60-
///
61-
/// # Panics
47+
/// let value = 0u32;
6248
///
63-
/// This method never panics.
49+
/// let volatile = Volatile::new(&value);
50+
/// assert_eq!(volatile.read(), 0);
51+
/// ```
6452
pub const fn new(value: T) -> Volatile<T> {
6553
Volatile {
6654
value,
@@ -70,22 +58,22 @@ impl<T> Volatile<T> {
7058
}
7159

7260
impl<T: Copy, A> Volatile<&T, A> {
73-
/// Performs a volatile read of the contained value, returning a copy
74-
/// of the read value. Volatile reads are guaranteed not to be optimized
61+
/// Performs a volatile read of the contained value.
62+
///
63+
/// Returns a copy of the read value. Volatile reads are guaranteed not to be optimized
7564
/// away by the compiler, but by themselves do not have atomic ordering
7665
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper type.
7766
///
67+
/// ## Example
68+
///
7869
/// ```rust
7970
/// use volatile::Volatile;
8071
///
81-
/// let value = Volatile::new(42u32);
72+
/// let value = 42;
73+
/// let volatile = Volatile::new(&value);
8274
///
83-
/// assert_eq!(value.read(), 42u32);
75+
/// assert_eq!(volatile.read(), 42);
8476
/// ```
85-
///
86-
/// # Panics
87-
///
88-
/// This method never panics.
8977
pub fn read(&self) -> T
9078
where
9179
A: Readable,
@@ -96,22 +84,22 @@ impl<T: Copy, A> Volatile<&T, A> {
9684
}
9785

9886
impl<T: Copy, A> Volatile<&mut T, A> {
99-
/// Performs a volatile read of the contained value, returning a copy
100-
/// of the read value. Volatile reads are guaranteed not to be optimized
87+
/// Performs a volatile read of the contained value.
88+
///
89+
/// Returns a copy of the read value. Volatile reads are guaranteed not to be optimized
10190
/// away by the compiler, but by themselves do not have atomic ordering
10291
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper type.
10392
///
93+
/// ## Example
94+
///
10495
/// ```rust
10596
/// use volatile::Volatile;
10697
///
107-
/// let value = Volatile::new(42u32);
98+
/// let mut value = 42;
99+
/// let volatile = Volatile::new(&mut value);
108100
///
109-
/// assert_eq!(value.read(), 42u32);
101+
/// assert_eq!(volatile.read(), 42);
110102
/// ```
111-
///
112-
/// # Panics
113-
///
114-
/// This method never panics.
115103
pub fn read(&self) -> T
116104
where
117105
A: Readable,
@@ -120,24 +108,23 @@ impl<T: Copy, A> Volatile<&mut T, A> {
120108
unsafe { ptr::read_volatile(self.value) }
121109
}
122110

123-
/// Performs a volatile write, setting the contained value to the given value `value`. Volatile
124-
/// writes are guaranteed to not be optimized away by the compiler, but by themselves do not
125-
/// have atomic ordering guarantees. To also get atomicity, consider looking at the `Atomic`
126-
/// wrapper type.
111+
/// Performs a volatile write, setting the contained value to the given `value`.
112+
///
113+
/// Volatile writes are guaranteed to not be optimized away by the compiler, but by
114+
/// themselves do not have atomic ordering guarantees. To also get atomicity, consider
115+
/// looking at the `Atomic` wrapper type.
116+
///
117+
/// ## Example
127118
///
128119
/// ```rust
129120
/// use volatile::Volatile;
130121
///
131-
/// let mut value = Volatile::new(0u32);
122+
/// let mut value = 42;
123+
/// let mut volatile = Volatile::new(&mut value);
124+
/// volatile.write(50);
132125
///
133-
/// value.write(42u32);
134-
///
135-
/// assert_eq!(value.read(), 42u32);
126+
/// assert_eq!(volatile.read(), 50);
136127
/// ```
137-
///
138-
/// # Panics
139-
///
140-
/// This method never panics.
141128
pub fn write(&mut self, value: T)
142129
where
143130
A: Writable,
@@ -146,23 +133,21 @@ impl<T: Copy, A> Volatile<&mut T, A> {
146133
unsafe { ptr::write_volatile(self.value, value) };
147134
}
148135

136+
/// Updates the contained value using the given closure and volatile instructions.
137+
///
149138
/// Performs a volatile read of the contained value, passes a mutable reference to it to the
150139
/// function `f`, and then performs a volatile write of the (potentially updated) value back to
151140
/// the contained value.
152141
///
153142
/// ```rust
154143
/// use volatile::Volatile;
155144
///
156-
/// let mut value = Volatile::new(21u32);
145+
/// let mut value = 42;
146+
/// let mut volatile = Volatile::new(&mut value);
147+
/// volatile.update(|val| *val += 1);
157148
///
158-
/// value.update(|val_ref| *val_ref *= 2);
159-
///
160-
/// assert_eq!(value.read(), 42u32);
149+
/// assert_eq!(volatile.read(), 43);
161150
/// ```
162-
///
163-
/// # Panics
164-
///
165-
/// Ths method never panics.
166151
pub fn update<F>(&mut self, f: F)
167152
where
168153
F: FnOnce(&mut T),

0 commit comments

Comments
 (0)