Expand description
Macro to define register layout and accessors.
The register! macro provides an intuitive and readable syntax for
defining a dedicated type for each register and accessing it using Io. Each such
type comes with its own field accessors that can return an error if a field’s value is invalid.
Note: most of the items in this module are public so they can be referenced by the macro, but
most are not to be used directly by users. Outside of the register! macro itself, the only
items you might want to import from this module are WithBase and Array.
§Simple example
use kernel::io::register;
register! {
/// Basic information about the chip.
pub BOOT_0(u32) @ 0x00000100 {
/// Vendor ID.
15:8 vendor_id;
/// Major revision of the chip.
7:4 major_revision;
/// Minor revision of the chip.
3:0 minor_revision;
}
}This defines a 32-bit BOOT_0 type which can be read from or written to offset 0x100 of an
Io region, with the described bitfields. For instance, minor_revision consists of the 4
least significant bits of the type.
Fields are instances of Bounded and can be read by calling their
getter method, which is named after them. They also have setter methods prefixed with with_
for runtime values and with_const_ for constant values. All setters return the updated
register value.
Fields can also be transparently converted from/to an arbitrary type by using the => and
?=> syntaxes.
If present, doc comments above register or fields definitions are added to the relevant item they document (the register type itself, or the field’s setter and getter methods).
Note that multiple registers can be defined in a single register! invocation. This can be
useful to group related registers together.
Here is how the register defined above can be used in code:
use kernel::{
io::{
register,
Io,
IoLoc,
},
num::Bounded,
};
// Read from the register's defined offset (0x100).
let boot0 = io.read(BOOT_0);
pr_info!("chip revision: {}.{}", boot0.major_revision().get(), boot0.minor_revision().get());
// Update some fields and write the new value back.
let new_boot0 = boot0
// Constant values.
.with_const_major_revision::<3>()
.with_const_minor_revision::<10>()
// Runtime value.
.with_vendor_id(obtain_vendor_id());
io.write_reg(new_boot0);
// Or, build a new value from zero and write it:
io.write_reg(BOOT_0::zeroed()
.with_const_major_revision::<3>()
.with_const_minor_revision::<10>()
.with_vendor_id(obtain_vendor_id())
);
// Or, read and update the register in a single step.
io.update(BOOT_0, |r| r
.with_const_major_revision::<3>()
.with_const_minor_revision::<10>()
.with_vendor_id(obtain_vendor_id())
);
// Constant values can also be built using the const setters.
const V: BOOT_0 = pin_init::zeroed::<BOOT_0>()
.with_const_major_revision::<3>()
.with_const_minor_revision::<10>();For more extensive documentation about how to define registers, see the
register! macro.
Structs§
- Fixed
Register Loc - Location of a fixed register.
- Register
Array Loc - Location of an array register.
- Relative
Register Array Loc - Location of a relative array register.
- Relative
Register Loc - Location of a relative register.
Traits§
- Array
- Trait providing location builders for
RegisterArrays. - Fixed
Register - Trait implemented by registers with a fixed offset.
- Located
Register - Trait implemented by items that contain both a register value and the absolute I/O location at which to write it.
- Register
- Trait implemented by all registers.
- Register
Array - Trait implemented by arrays of registers.
- Register
Base - Trait providing a base address to be added to the offset of a relative register to obtain its actual offset.
- Relative
Register - Trait implemented by relative registers.
- Relative
Register Array - Trait implemented by arrays of relative registers.
- With
Base - Trait implemented by all registers that are relative to a base.