From a76f650c465edc33142121504e8aab58c5aa3622 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 15 Feb 2024 15:43:25 +0100 Subject: [PATCH] Started --- rtic-sync/Cargo.toml | 1 + rtic-sync/src/bit_channel.rs | 89 ++++++++++++++++++++++++++++++++++++ rtic-sync/src/lib.rs | 3 +- 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 rtic-sync/src/bit_channel.rs diff --git a/rtic-sync/Cargo.toml b/rtic-sync/Cargo.toml index 7df193d1e3..234a051df2 100644 --- a/rtic-sync/Cargo.toml +++ b/rtic-sync/Cargo.toml @@ -28,6 +28,7 @@ portable-atomic = { version = "1", default-features = false } embedded-hal = { version = "1.0", optional = true } embedded-hal-async = { version = "1.0", optional = true } embedded-hal-bus = { version = "0.1.0", optional = true, features = ["async"] } +bitflags = "2" [dev-dependencies] tokio = { version = "1", features = ["rt", "macros", "time"] } diff --git a/rtic-sync/src/bit_channel.rs b/rtic-sync/src/bit_channel.rs new file mode 100644 index 0000000000..703d351a64 --- /dev/null +++ b/rtic-sync/src/bit_channel.rs @@ -0,0 +1,89 @@ +//! A channel operating on bitflags. + +use bitflags::{Bits, Flags}; +use core::sync::atomic::{AtomicU16, AtomicU8, Ordering}; + +// +// Bit channel +// + +pub struct BitChannel +where + T: Flags, + T::Bits: AtomicType, +{ + atomic: ::Atomic, +} + +impl BitChannel +where + T: Flags, + T::Bits: AtomicType, +{ + pub const fn new() -> Self { + BitChannel { + atomic: T::Bits::ATOMIC_ZERO, + } + } + + pub fn test(&self) { + T::Bits::fetch_and(&self.atomic, T::Bits::EMPTY, Ordering::Relaxed); + } +} + +pub trait AtomicType: Sized { + type Atomic: From; + + const ATOMIC_ZERO: Self::Atomic; + + fn fetch_and(a: &Self::Atomic, b: Self, order: Ordering) -> Self; +} + +impl AtomicType for u16 { + type Atomic = AtomicU16; + + const ATOMIC_ZERO: Self::Atomic = AtomicU16::new(0); + + fn fetch_and(a: &Self::Atomic, b: Self, order: Ordering) -> Self { + a.fetch_and(b, order) + } +} + +impl AtomicType for u8 { + type Atomic = AtomicU8; + + const ATOMIC_ZERO: Self::Atomic = AtomicU8::new(0); + + fn fetch_and(a: &Self::Atomic, b: Self, order: Ordering) -> Self { + a.fetch_and(b, order) + } +} + +// etc... + +#[cfg(test)] +mod tests { + use super::*; + use bitflags::bitflags; + + bitflags! { + struct FlagsU8: u8 { + const A = 1; + const B = 2; + } + } + + bitflags! { + struct FlagsU16: u16 { + const A = 1; + const B = 2; + } + } + + #[test] + fn test() { + let a = BitChannel::::new(); + let b = BitChannel::::new(); + } +} + diff --git a/rtic-sync/src/lib.rs b/rtic-sync/src/lib.rs index ecd3247d5a..ba30f69a92 100644 --- a/rtic-sync/src/lib.rs +++ b/rtic-sync/src/lib.rs @@ -1,9 +1,10 @@ //! Synchronization primitives for asynchronous contexts. #![no_std] -#![deny(missing_docs)] +#![warn(missing_docs)] pub mod arbiter; +pub mod bit_channel; pub mod channel; pub use portable_atomic;