pub struct AtomicDevice<'a, T> { /* private fields */ }
Expand description
Atomics-based shared bus I2c
implementation.
Sharing is implemented with a AtomicDevice
, which consists of an UnsafeCell
and an AtomicBool
“locked” flag.
This means it has low overhead, like RefCellDevice
. Aditionally, it is Send
,
which allows sharing a single bus across multiple threads (interrupt priority level), like CriticalSectionDevice
,
while not using critical sections and therefore impacting real-time performance less.
The downside is using a simple AtomicBool
for locking doesn’t prevent two threads from trying to lock it at once.
For example, the main thread can be doing an I2C transaction, and an interrupt fires and tries to do another. In this
case, a Busy
error is returned that must be handled somehow, usually dropping the data or trying again later.
Note that retrying in a loop on Busy
errors usually leads to deadlocks. In the above example, it’ll prevent the
interrupt handler from returning, which will starve the main thread and prevent it from releasing the lock. If
this is an issue for your use case, you most likely should use CriticalSectionDevice
instead.
This primitive is particularly well-suited for applications that have external arbitration
rules that prevent Busy
errors in the first place, such as the RTIC framework.
§Examples
Assuming there is a pressure sensor with address 0x42
on the same bus as a temperature sensor
with address 0x20
; AtomicDevice
can be used to give access to both of these sensors
from a single i2c
instance.
use embedded_hal_bus::i2c;
use embedded_hal_bus::util::AtomicCell;
let i2c = hal.i2c();
let i2c_cell = AtomicCell::new(i2c);
let mut temperature_sensor = TemperatureSensor::new(
i2c::AtomicDevice::new(&i2c_cell),
0x20,
);
let mut pressure_sensor = PressureSensor::new(
i2c::AtomicDevice::new(&i2c_cell),
0x42,
);
Implementations§
source§impl<'a, T> AtomicDevice<'a, T>where
T: I2c,
impl<'a, T> AtomicDevice<'a, T>where
T: I2c,
sourcepub fn new(bus: &'a AtomicCell<T>) -> Self
pub fn new(bus: &'a AtomicCell<T>) -> Self
Create a new AtomicDevice
.
Trait Implementations§
source§impl<'a, T> ErrorType for AtomicDevice<'a, T>where
T: I2c,
impl<'a, T> ErrorType for AtomicDevice<'a, T>where
T: I2c,
source§impl<'a, T> I2c for AtomicDevice<'a, T>where
T: I2c,
impl<'a, T> I2c for AtomicDevice<'a, T>where
T: I2c,
source§fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error>
fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error>
address
. Read more