Skip to content

Commit 12f4b79

Browse files
committed
tock-register-interface: move IntLike, RegisterLongName, ...
Move IntLike, RegisterLongName out of crate::registers to the top-level crate and TryFromValue to crate::fields respectively. These traits are independent and should therefore not be included in the registers module. The reasoning for moving IntLike and RegisterLongName to the top-level crate exports is that these are base types over which all registers and fields are composed, and thus represent essential functionality of the library. TryFromValue only relates to individual register fields and is thus moved to crate::fields. Other code in the Tock repository is updated to reflect these changes. Signed-off-by: Leon Schuermann <leon@is.currently.online>
1 parent 381ec02 commit 12f4b79

File tree

4 files changed

+92
-75
lines changed

4 files changed

+92
-75
lines changed

libraries/tock-register-interface/src/fields.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//!
1010
//! A specific section (bitfield) in a register is described by the
1111
//! [`Field`] type, consisting of an unshifted bitmask over the base
12-
//! register [`IntLike`](crate::registers::IntLike) type, and a shift
12+
//! register [`IntLike`](crate::IntLike) type, and a shift
1313
//! parameter. It is further associated with a specific
1414
//! [`RegisterLongName`], which can prevent its use with incompatible
1515
//! registers.
@@ -23,9 +23,9 @@
2323
//! ## `register_bitfields` macro
2424
//!
2525
//! For defining register layouts with an associated
26-
//! [`RegisterLongName`](crate::registers::RegisterLongName), along
27-
//! with [`Field`]s and matching [`FieldValue`]s, a convenient
28-
//! macro-based interface can be used.
26+
//! [`RegisterLongName`](crate::RegisterLongName), along with
27+
//! [`Field`]s and matching [`FieldValue`]s, a convenient macro-based
28+
//! interface can be used.
2929
//!
3030
//! The following example demonstrates how two registers can be
3131
//! defined, over a `u32` base type:
@@ -59,7 +59,6 @@
5959
//! assert!(reg.get() == 0x00000008);
6060
//! ```
6161
62-
6362
// The register interface uses `+` in a way that is fine for bitfields, but
6463
// looks unusual (and perhaps problematic) to a linter. We just ignore those
6564
// lints for this file.
@@ -69,8 +68,7 @@
6968
use core::marker::PhantomData;
7069
use core::ops::{Add, AddAssign};
7170

72-
use crate::registers::TryFromValue;
73-
use crate::registers::{IntLike, RegisterLongName};
71+
use crate::{IntLike, RegisterLongName};
7472

7573
/// Specific section of a register.
7674
///
@@ -249,6 +247,14 @@ impl<T: IntLike, R: RegisterLongName> AddAssign for FieldValue<T, R> {
249247
}
250248
}
251249

250+
/// Conversion of raw register value into enumerated values member.
251+
/// Implemented inside register_bitfields! macro for each bit field.
252+
pub trait TryFromValue<V> {
253+
type EnumType;
254+
255+
fn try_from(v: V) -> Option<Self::EnumType>;
256+
}
257+
252258
/// Helper macro for computing bitmask of variable number of bits
253259
#[macro_export]
254260
macro_rules! bitmask {
@@ -322,8 +328,7 @@ macro_rules! register_bitmasks {
322328
$(#[$outer])*
323329
pub mod $field {
324330
#[allow(unused_imports)]
325-
use $crate::registers::TryFromValue;
326-
use $crate::fields::FieldValue;
331+
use $crate::fields::{TryFromValue, FieldValue};
327332
use super::$reg_desc;
328333

329334
$(
@@ -389,8 +394,7 @@ macro_rules! register_bitmasks {
389394
$(#[$outer])*
390395
pub mod $field {
391396
#[allow(unused_imports)]
392-
use $crate::registers::TryFromValue;
393-
use $crate::fields::FieldValue;
397+
use $crate::fields::{FieldValue, TryFromValue};
394398
use super::$reg_desc;
395399

396400
#[allow(non_upper_case_globals)]
@@ -438,7 +442,7 @@ macro_rules! register_bitfields {
438442
// (if you can access $reg, you can access $reg::Register)
439443
#[derive(Clone, Copy)]
440444
pub struct Register;
441-
impl $crate::registers::RegisterLongName for Register {}
445+
impl $crate::RegisterLongName for Register {}
442446

443447
use $crate::fields::Field;
444448

libraries/tock-register-interface/src/interfaces.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
//!
88
//! Each trait has two associated type parameters, namely:
99
//!
10-
//! - `T`: [`IntLike`](crate::registers::IntLike), indicating the
11-
//! underlying integer type used to represent the register's raw
12-
//! contents.
10+
//! - `T`: [`IntLike`](crate::IntLike), indicating the underlying
11+
//! integer type used to represent the register's raw contents.
1312
//!
14-
//! - `R`: [`RegisterLongName`](crate::registers::RegisterLongName),
15-
//! functioning as a type to identify this register's descriptive
16-
//! name and semantic meaning. It is further used to impose type
17-
//! constraints on values passed through the API, such as
13+
//! - `R`: [`RegisterLongName`](crate::RegisterLongName), functioning
14+
//! as a type to identify this register's descriptive name and
15+
//! semantic meaning. It is further used to impose type constraints
16+
//! on values passed through the API, such as
1817
//! [`FieldValue`](crate::fields::FieldValue).
1918
//!
2019
//! Registers can have different access levels, which are mapped to
@@ -35,10 +34,9 @@
3534
//! example a memory-mapped UART register might transmit when
3635
//! writing and receive when reading.
3736
//!
38-
//! If a type implements both [`Readable`] and [`Writeable`], and the
39-
//! associated
40-
//! [`RegisterLongName`](crate::registers::RegisterLongName) type
41-
//! parameters are identical, it will automatically implement
37+
//! If a type implements both [`Readable`] and [`Writeable`], and
38+
//! the associated [`RegisterLongName`](crate::RegisterLongName)
39+
//! type parameters are identical, it will automatically implement
4240
//! [`ReadWriteable`]. In particular, for
4341
//! [`Aliased`](crate::registers::Aliased) this is -- in general --
4442
//! not the case, so
@@ -91,7 +89,7 @@
9189
//! # use core::marker::PhantomData;
9290
//! #
9391
//! # use tock_registers::interfaces::{Readable, Writeable, ReadWriteable};
94-
//! # use tock_registers::registers::RegisterLongName;
92+
//! # use tock_registers::RegisterLongName;
9593
//! # use tock_registers::register_bitfields;
9694
//! #
9795
//! struct DummyRegister<'a, R: RegisterLongName> {
@@ -149,8 +147,9 @@
149147
//! assert!(dummy.read(DummyReg::HIGH) == 0xb);
150148
//! ```
151149
152-
use crate::fields::{Field, FieldValue};
153-
use crate::registers::{IntLike, LocalRegisterCopy, RegisterLongName, TryFromValue};
150+
use crate::fields::{Field, FieldValue, TryFromValue};
151+
use crate::registers::LocalRegisterCopy;
152+
use crate::{IntLike, RegisterLongName};
154153

155154
/// Readable register
156155
///

libraries/tock-register-interface/src/lib.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,62 @@ pub mod fields;
99
pub mod interfaces;
1010
pub mod macros;
1111
pub mod registers;
12+
13+
use core::ops::{BitAnd, BitOr, BitOrAssign, Not, Shl, Shr};
14+
15+
/// Trait representing the base type of registers.
16+
///
17+
/// IntLike defines basic properties of types required to
18+
/// read/write/modify a register through its methods and supertrait
19+
/// requirements.
20+
///
21+
/// It features a range of default implementations for common integer
22+
/// types, such as [`u8`], [`u16`], [`u32`], [`u64`], [`u128`] and
23+
/// [`usize`].
24+
pub trait IntLike:
25+
BitAnd<Output = Self>
26+
+ BitOr<Output = Self>
27+
+ BitOrAssign
28+
+ Not<Output = Self>
29+
+ Eq
30+
+ Shr<usize, Output = Self>
31+
+ Shl<usize, Output = Self>
32+
+ Copy
33+
+ Clone
34+
{
35+
/// Return the representation of the value `0` in the implementing
36+
/// type.
37+
///
38+
/// This can be used to acquire values of the [`IntLike`] type,
39+
/// even in generic implementations. For instance, to get the
40+
/// value `1`, one can use `<T as IntLike>::zero() + 1`. To get
41+
/// the largest representable value, use a bitwise negation: `~(<T
42+
/// as IntLike>::zero())`.
43+
fn zero() -> Self;
44+
}
45+
46+
// Helper macro for implementing the IntLike trait on differrent
47+
// types.
48+
macro_rules! IntLike_impl_for {
49+
($type:ty) => {
50+
impl IntLike for $type {
51+
fn zero() -> Self {
52+
0
53+
}
54+
}
55+
};
56+
}
57+
58+
IntLike_impl_for!(u8);
59+
IntLike_impl_for!(u16);
60+
IntLike_impl_for!(u32);
61+
IntLike_impl_for!(u64);
62+
IntLike_impl_for!(u128);
63+
IntLike_impl_for!(usize);
64+
65+
/// Descriptive name for each register.
66+
pub trait RegisterLongName {}
67+
68+
// Useful implementation for when no RegisterLongName is required
69+
// (e.g. no fields need to be accessed, just the raw register values)
70+
impl RegisterLongName for () {}

libraries/tock-register-interface/src/registers.rs

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -56,55 +56,10 @@
5656
use core::cell::UnsafeCell;
5757
use core::fmt;
5858
use core::marker::PhantomData;
59-
use core::ops::{BitAnd, BitOr, BitOrAssign, Not, Shl, Shr};
6059

61-
use crate::fields::{Field, FieldValue};
60+
use crate::fields::{Field, FieldValue, TryFromValue};
6261
use crate::interfaces::{Readable, Writeable};
63-
64-
/// IntLike properties needed to read/write/modify a register.
65-
pub trait IntLike:
66-
BitAnd<Output = Self>
67-
+ BitOr<Output = Self>
68-
+ BitOrAssign
69-
+ Not<Output = Self>
70-
+ Eq
71-
+ Shr<usize, Output = Self>
72-
+ Shl<usize, Output = Self>
73-
+ Copy
74-
+ Clone
75-
{
76-
fn zero() -> Self;
77-
}
78-
79-
macro_rules! IntLike_impl_for {
80-
($type:ty) => {
81-
impl IntLike for $type {
82-
fn zero() -> Self {
83-
0
84-
}
85-
}
86-
};
87-
}
88-
89-
IntLike_impl_for!(u8);
90-
IntLike_impl_for!(u16);
91-
IntLike_impl_for!(u32);
92-
IntLike_impl_for!(u64);
93-
IntLike_impl_for!(u128);
94-
IntLike_impl_for!(usize);
95-
96-
/// Descriptive name for each register.
97-
pub trait RegisterLongName {}
98-
99-
impl RegisterLongName for () {}
100-
101-
/// Conversion of raw register value into enumerated values member.
102-
/// Implemented inside register_bitfields! macro for each bit field.
103-
pub trait TryFromValue<V> {
104-
type EnumType;
105-
106-
fn try_from(v: V) -> Option<Self::EnumType>;
107-
}
62+
use crate::{IntLike, RegisterLongName};
10863

10964
/// Read/Write registers.
11065
///
@@ -395,14 +350,14 @@ mod tests {
395350
Foo7,
396351
}
397352

398-
impl super::TryFromValue<u16> for Foo {
353+
impl crate::fields::TryFromValue<u16> for Foo {
399354
type EnumType = Foo;
400355

401356
fn try_from(v: u16) -> Option<Self::EnumType> {
402357
Self::try_from(v as u32)
403358
}
404359
}
405-
impl super::TryFromValue<u32> for Foo {
360+
impl crate::fields::TryFromValue<u32> for Foo {
406361
type EnumType = Foo;
407362

408363
fn try_from(v: u32) -> Option<Self::EnumType> {

0 commit comments

Comments
 (0)