All Projects → Rahix → shared-bus

Rahix / shared-bus

Licence: other
Crate for sharing buses between multiple devices

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to shared-bus

app-template
Quickly set up a `probe-run` + `defmt` + `flip-link` embedded project
Stars: ✭ 171 (+155.22%)
Mutual labels:  embedded-rust
embedded-ccs811-rs
Platform agnostic Rust driver for the CCS811 ultra-low power digital gas sensor for monitoring indoor air quality
Stars: ✭ 12 (-82.09%)
Mutual labels:  embedded-hal
stm32f7xx-hal
A Rust embedded-hal HAL for all MCUs in the STM32 F7 family
Stars: ✭ 71 (+5.97%)
Mutual labels:  embedded-rust
stm32wb-hal
[WIP] embedded-hal for the STM32WB family of microcontrollers
Stars: ✭ 19 (-71.64%)
Mutual labels:  embedded-hal
stm32-rustup
A guide to rust your stm32 microcontroller
Stars: ✭ 25 (-62.69%)
Mutual labels:  embedded-rust
psila
Work in progress Zigbee stack in Rust
Stars: ✭ 20 (-70.15%)
Mutual labels:  embedded-rust
r3
R3-OS — Experimental static (μITRON-esque) RTOS for deeply embedded systems, testing the limit of Rust's const eval and generics
Stars: ✭ 87 (+29.85%)
Mutual labels:  embedded-rust
nuclei-sdk
Nuclei RISC-V Software Development Kit
Stars: ✭ 65 (-2.99%)
Mutual labels:  embedded-hal
ssd1675
Rust driver for SSD1675 e-Paper display controller
Stars: ✭ 56 (-16.42%)
Mutual labels:  embedded-hal
embedded-svc
Rust APIs and abstractions for various embedded services (WiFi, Network, Httpd, Logging, etc.)
Stars: ✭ 72 (+7.46%)
Mutual labels:  embedded-hal
mfrc522
A platform agnostic driver to interface the MFRC522 (RFID reader/writer)
Stars: ✭ 27 (-59.7%)
Mutual labels:  embedded-hal
pwm-pca9685-rs
Platform-agnostic Rust driver for the PCA9685 I2C 16-channel, 12-bit PWM/Servo/LED controller
Stars: ✭ 19 (-71.64%)
Mutual labels:  embedded-hal
esp-idf-hal
embedded-hal implementation for Rust on ESP32 and ESP-IDF
Stars: ✭ 42 (-37.31%)
Mutual labels:  embedded-hal
Rust Raspberrypi Os Tutorials
📚 Learn to write an embedded OS in Rust 🦀
Stars: ✭ 7,275 (+10758.21%)
Mutual labels:  embedded-rust
hd44780-driver
Implementation of the embedded-hal traits for the HD44780.
Stars: ✭ 21 (-68.66%)
Mutual labels:  embedded-rust

shared-bus crates.io page docs.rs Continuous Integration

shared-bus is a crate to allow sharing bus peripherals safely between multiple devices.

In the embedded-hal ecosystem, it is convention for drivers to "own" the bus peripheral they are operating on. This implies that only one driver can have access to a certain bus. That, of course, poses an issue when multiple devices are connected to a single bus.

shared-bus solves this by giving each driver a bus-proxy to own which internally manages access to the actual bus in a safe manner. For a more in-depth introduction of the problem this crate is trying to solve, take a look at the blog post.

There are different 'bus managers' for different use-cases:

Sharing within a single task/thread

As long as all users of a bus are contained in a single task/thread, bus sharing is very simple. With no concurrency possible, no special synchronization is needed. This is where a BusManagerSimple should 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();

The BusManager::acquire_*() methods can be called as often as needed; each call will yield a new bus-proxy of the requested type.

Sharing across multiple tasks/threads

For sharing across multiple tasks/threads, synchronization is needed to ensure all bus-accesses are strictly serialized and can't race against each other. The synchronization is handled by a platform-specific BusMutex implementation. shared-bus already contains some implementations for common targets. For each one, there is also a macro for easily creating a bus-manager with 'static lifetime, which is almost always a requirement when sharing across task/thread boundaries. As an example:

// 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:
# let t =
std::thread::spawn(move || {
    my_device.do_something_on_the_bus();
});
# t.join().unwrap();

Those platform-specific bits are guarded by a feature that needs to be enabled. Here is an overview of what's already available:

Mutex Bus Manager 'static Bus Macro Feature Name
std::sync::Mutex BusManagerStd new_std!() std
cortex_m::interrupt::Mutex BusManagerCortexM new_cortexm!() cortex-m
NA BusManagerAtomicCheck new_atomic_check!() cortex-m

Supported Busses

Currently, the following busses can be shared with shared-bus:

Bus Proxy Type Acquire Method Comments
I2C I2cProxy .acquire_i2c()
SPI SpiProxy .acquire_spi() SPI can only be shared within a single task (See SpiProxy for details).

License

shared-bus is licensed under either of

at your option.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].