Registers
This crate is a simple procedural macro based crate for working with registers. The goal is to make supporting complex register fields as intuitive and safe as possible.
Quickstart
Take for example the First Common PCIe Header Register:
The above declaration automatically generate implementations to work with the register in a safe manner:
const PCIE_HEADER_0_ADDR: *const u32 = 0xDEADBEEF as *const u32;
let mut reg = new;
unsafe
println!;
println!;
Registers are RW by default, and either can be disabled by specifying read = false or write = false. This will toggle whether or not the PCIeHeader0::read() or PCIeHeader0::write() methods are implemented or not.
This same behaviour is supported per-field as well in the same manner, toggling if get_*() and set_*() methods are implemented.
Out of bounds writes are protected as well:
let foo = new;
assert!;
There is no need to explicitly declare reserved bytes, though you can if you wish by marking both read and write as false.
Signed fields are supported (2s complement) by changing the type of the field to i:
let foo = new;
assert!;
assert!;
This will cause the get_* and set_* to return and take in signed integer values, respectively.
Overhead
The size of a register struct is guranteed to be no bigger than the underlying register itself, so the generated register struct for a 32 bit register is guranteed to be no larger than 32 bits.
Alternatives
- tock-registers - Another macro based register library
License
This project is licensed under the MIT License.