pub struct BusManager<M> { /* private fields */ }
Expand description

“Manager” for a shared bus.

The manager owns the original bus peripheral (wrapped inside a mutex) and hands out proxies which can be used by device drivers for accessing the bus. Certain bus proxies can only be created with restrictions (see the individual methods for details).

Usually the type-aliases defined in this crate should be used instead of BusManager directly. Otherwise, the mutex type needs to be specified explicitly. Here is an overview of aliases (some are only available if a certain feature is enabled):

Bus ManagerMutex TypeFeature NameNotes
BusManagerSimpleshared_bus::NullMutexalways availableFor sharing within a single execution context.
BusManagerStdstd::sync::MutexstdFor platforms where std is available.
BusManagerCortexMcortex_m::interrupt::Mutexcortex-mFor Cortex-M platforms; Uses a critcal section (i.e. turns off interrupts during bus transactions).

Constructing a BusManager

There are two ways to instanciate a bus manager. Which one to use depends on the kind of sharing that is intended.

  1. When all bus users live in the same task/thread, a BusManagerSimple can be used:

    // For example:
    // let i2c = I2c::i2c1(dp.I2C1, (scl, sda), 90.khz(), clocks, &mut rcc.apb1);
    
    let bus = shared_bus::BusManagerSimple::new(i2c);
    
    let mut proxy1 = bus.acquire_i2c();
    let mut my_device = MyDevice::new(bus.acquire_i2c());
    
    proxy1.write(0x39, &[0xc0, 0xff, 0xee]);
    my_device.do_something_on_the_bus();
  2. When users are in different execution contexts, a proper mutex type is needed and the manager must be made static to ensure it lives long enough. For this, shared-bus provides a number of macros creating such a static instance:

    // For example:
    // let i2c = I2c::i2c1(dp.I2C1, (scl, sda), 90.khz(), clocks, &mut rcc.apb1);
    
    // The bus is a 'static reference -> it lives forever and references can be
    // shared with other threads.
    let bus: &'static _ = shared_bus::new_std!(SomeI2cBus = i2c).unwrap();
    
    let mut proxy1 = bus.acquire_i2c();
    let mut my_device = MyDevice::new(bus.acquire_i2c());
    
    // We can easily move a proxy to another thread:
    std::thread::spawn(move || {
        my_device.do_something_on_the_bus();
    });

    For other platforms, similar macros exist (e.g. new_cortexm!()).

Implementations

Create a new bus manager for a bus.

See the documentation for BusManager for more details.

Acquire an I2cProxy for this bus.

The returned proxy object can then be used for accessing the bus by e.g. a driver:

let bus = shared_bus::BusManagerSimple::new(i2c);

let mut proxy1 = bus.acquire_i2c();
let mut my_device = MyDevice::new(bus.acquire_i2c());

proxy1.write(0x39, &[0xc0, 0xff, 0xee]);
my_device.do_something_on_the_bus();

Acquire an AdcProxy for this hardware block.

The returned proxy object can then be used for accessing the bus by e.g. a driver:

// For example:
// let ch0 = gpioa.pa0.into_analog(&mut gpioa.crl);
// let ch1 = gpioa.pa1.into_analog(&mut gpioa.crl);
// let adc = Adc::adc1(p.ADC1, &mut rcc.apb2, clocks);

let adc_bus: &'static _ = shared_bus::new_cortexm!(Adc<ADC1> = adc).unwrap();
let mut proxy1 = adc_bus.acquire_adc();
let mut proxy2 = adc_bus.acquire_adc();

proxy1.read(ch0).unwrap();
proxy2.read(ch1).unwrap();

Acquire an SpiProxy for this bus.

Note: SPI Proxies can only be created from BusManagerSimple (= bus managers using the NullMutex). See SpiProxy for more details why.

The returned proxy object can then be used for accessing the bus by e.g. a driver:

let bus = shared_bus::BusManagerSimple::new(spi);

let mut proxy1 = bus.acquire_spi();
let mut my_device = MyDevice::new(bus.acquire_spi());

// Chip-select needs to be managed manually
cs1.set_high();
proxy1.write(&[0xc0, 0xff, 0xee]);
cs1.set_low();

my_device.do_something_on_the_bus();

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.