diff --git a/embedded-hal-bus/Cargo.toml b/embedded-hal-bus/Cargo.toml index 07bff536..1ef572e9 100644 --- a/embedded-hal-bus/Cargo.toml +++ b/embedded-hal-bus/Cargo.toml @@ -17,23 +17,17 @@ version = "0.2.0" [features] # Enable shared bus implementations using `std::sync::Mutex`, and implement `std::error::Error` for `DeviceError` std = [] -# Enable shared bus implementations that require Atomic CAS operations -atomic-device = [] +# Use `portable-atomic` to enable `atomic-device` on devices without native atomic CAS +# +# `portable-atomic` emulates atomic CAS functionality, allowing `embedded-hal-bus` to use `atomic-device` on hardware +# that does not natively support atomic CAS. If you enable this, you must also add `portable-atomic` to your crate with +# a feature flag such as `unsafe-assume-single-core` or `critical-section` to choose how atomic CAS is implemented. +# See https://docs.rs/portable-atomic/1.7.0/portable_atomic/#optional-features for more info. +portable-atomic = [] # Enable `embedded-hal-async` support. async = ["dep:embedded-hal-async"] # Derive `defmt::Format` from `defmt` 0.3 for enums and structs. See https://github.com/knurling-rs/defmt for more info defmt-03 = ["dep:defmt-03", "embedded-hal/defmt-03", "embedded-hal-async?/defmt-03"] -# Enable critical-section feature in portable-atomic. -# -# `portable-atomic` emulates atomic CAS functionality, allowing `embedded-hal-bus` to use `atomic-device` on hardware that does not natively support atomic CAS. -# This feature requires a critical-section implementation, which is most often provided by your arch crate (cortex-m / riscv / msp430 / avr-device / etc) when the `critical-section-single-core` feature is enabled. -# A list of critical-section impls is available [in the critical section docs](https://github.com/rust-embedded/critical-section?tab=readme-ov-file#usage-in-no-std-binaries) -portable-atomic-critical-section = ["atomic-device", "portable-atomic/critical-section"] -# Enable unsafe-assume-single-core feature of portable-atomic. -# -# `portable-atomic` emulates atomic CAS functionality, allowing `embedded-hal-bus` to use `atomic-device` on hardware that does not natively support atomic CAS. -# This feature is only safe on single core systems -portable-atomic-unsafe-assume-single-core = ["atomic-device", "portable-atomic/unsafe-assume-single-core"] [dependencies] embedded-hal = { version = "1.0.0", path = "../embedded-hal" } diff --git a/embedded-hal-bus/README.md b/embedded-hal-bus/README.md index 4922c7f5..c2d9a77c 100644 --- a/embedded-hal-bus/README.md +++ b/embedded-hal-bus/README.md @@ -31,17 +31,13 @@ provides mechanisms to obtain multiple `I2c` instances out of a single `I2c` ins ## Optional Cargo features - **`async`**: enable `embedded-hal-async` support. -- **`atomic-device`**: enable shared bus implementations that require Atomic CAS operations. - **`defmt-03`**: Derive `defmt::Format` from `defmt` 0.3 for enums and structs. -- **`portable-atomic-critical-section`**: Enable critical-section feature in portable-atomic. +- **`portable-atomic`**: Use `portable-atomic` to enable `atomic-device` on devices without native atomic CAS - `portable-atomic` emulates atomic CAS functionality, allowing `embedded-hal-bus` to use `atomic-device` on hardware that does not natively support atomic CAS. - This feature requires a critical-section implementation, which is most often provided by your arch crate (cortex-m / riscv / msp430 / avr-device / etc) when the `critical-section-single-core` feature is enabled. - A list of critical-section impls is available [in the critical section docs](https://github.com/rust-embedded/critical-section?tab=readme-ov-file#usage-in-no-std-binaries) -- **`portable-atomic-unsafe-assume-single-core`**: Enable unsafe-assume-single-core feature of portable-atomic. - - `portable-atomic` emulates atomic CAS functionality, allowing `embedded-hal-bus` to use `atomic-device` on hardware that does not natively support atomic CAS. - This feature is only safe on single core systems + `portable-atomic` emulates atomic CAS functionality, allowing `embedded-hal-bus` to use `atomic-device` on hardware + that does not natively support atomic CAS. If you enable this, you must also add `portable-atomic` to your crate with + a feature flag such as `unsafe-assume-single-core` or `critical-section` to choose how atomic CAS is implemented. + See https://docs.rs/portable-atomic/1.7.0/portable_atomic/#optional-features for more info. - **`std`**: enable shared bus implementations using `std::sync::Mutex`, and implement `std::error::Error` for `DeviceError`. diff --git a/embedded-hal-bus/src/i2c/mod.rs b/embedded-hal-bus/src/i2c/mod.rs index ef8f7ae9..0353ea71 100644 --- a/embedded-hal-bus/src/i2c/mod.rs +++ b/embedded-hal-bus/src/i2c/mod.rs @@ -8,7 +8,7 @@ mod mutex; pub use mutex::*; mod critical_section; pub use self::critical_section::*; -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] mod atomic; -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] pub use atomic::*; diff --git a/embedded-hal-bus/src/spi/mod.rs b/embedded-hal-bus/src/spi/mod.rs index a7ad6b98..c14c8fdc 100644 --- a/embedded-hal-bus/src/spi/mod.rs +++ b/embedded-hal-bus/src/spi/mod.rs @@ -11,11 +11,11 @@ pub use refcell::*; mod mutex; #[cfg(feature = "std")] pub use mutex::*; -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] mod atomic; mod critical_section; mod shared; -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] pub use atomic::*; pub use self::critical_section::*; diff --git a/embedded-hal-bus/src/util.rs b/embedded-hal-bus/src/util.rs index f0cb8f16..91add232 100644 --- a/embedded-hal-bus/src/util.rs +++ b/embedded-hal-bus/src/util.rs @@ -3,7 +3,7 @@ #[allow(unused_imports)] use core::cell::UnsafeCell; -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] /// Cell type used by [`spi::AtomicDevice`](crate::spi::AtomicDevice) and [`i2c::AtomicDevice`](crate::i2c::AtomicDevice). /// /// To use `AtomicDevice`, you must wrap the bus with this struct, and then @@ -12,12 +12,12 @@ pub struct AtomicCell { pub(crate) bus: UnsafeCell, pub(crate) busy: portable_atomic::AtomicBool, } -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] unsafe impl Send for AtomicCell {} -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] unsafe impl Sync for AtomicCell {} -#[cfg(any(feature = "atomic-device", target_has_atomic = "8"))] +#[cfg(any(feature = "portable-atomic", target_has_atomic = "8"))] impl AtomicCell { /// Create a new `AtomicCell` pub fn new(bus: BUS) -> Self {