rust-osdev / volatile

Apache License 2.0
70 stars 19 forks source link

Provide an example #8

Closed faulesocke closed 5 years ago

faulesocke commented 5 years ago

Hey there,

would it be possible, to provide a short but complete usage example, that allows, for example reading a volatile array?

From reading the source and the documentation I don't really get, how this thing works and how to make it perform volatile reads.

phil-opp commented 5 years ago

General Usage

The idea behind this crate is that you have a volatile memory location, for example the memory mapped register of some hardware device. Let's say there is an memory mapped u32 register at address 0xdead000. Normally we would create a reference to it using unsafe:

let register = unsafe{ &mut *(0xdead000 as *mut u32) };

However, this way the compiler doesn't know that the memory address is volatile and uses normal read/write operations to access it, which might be reordered or optimized out. To avoid this, we use the Volatile wrapper:

let register = unsafe{ &mut *(dead000 as *mut Volatile<u32>) };

Now we have to use special read/write methods of the Volatile wrapper that tell the compiler that each read/write should be performed exactly at the place where it is written and not optimized out.

Volatile Arrays

Volatile arrays are currently difficult to abstract because there are no const generics in Rust yet. You can either wrap the whole array in a Volatile or use an array of Volatiles (e.g. [Volatile<u32>; 100]). The first approach has the problem that each read/write has to load/store the complete array, even if only a single entry is accessed. The second approach can access individual entries but is slower when accessing many entries because the compiler generates many small memory accesses instead of a few large ones.

I hope that https://github.com/rust-lang/rust/pull/53645 is merged soon. It implements a first version of const generics. This would allows us to create a generic VolatileArray and VolatileSlice types, which would allow accessing an arbitrary number of array/slice elements with a single volatile read/write operation.


I hope this helps!

faulesocke commented 5 years ago

Wow, now I understood it, this approach is quite clever. Thanks a lot.