• Stars
    star
    129
  • Rank 279,262 (Top 6 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Crate for sharing buses between multiple devices

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
shared_bus::XtensaMutex (spin::Mutex in critical section) BusManagerXtensa Β new_xtensa!() xtensa
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).
ADC AdcProxy .acquire_adc()

License

shared-bus is licensed under either of

at your option.

More Repositories

1

avr-hal

embedded-hal abstractions for AVR microcontrollers
Rust
1,264
star
2

avr-device

Register access crate for AVR microcontrollers
Rust
170
star
3

avr-hal-template

cargo-generate template for avr-hal projects
Rust
125
star
4

visualizer2

OpenGL Audio Visualizers in Rust
Rust
94
star
5

tbot

Automation/Testing tool for Embedded Linux Development
Python
84
star
6

spacestation

A procedural spacestation generator
Hy
25
star
7

port-expander

Abstraction for IΒ²C port-expanders
Rust
17
star
8

atdf2svd

Converter from Atmel's atdf format to CMSIS SVD
Rust
17
star
9

pa-visualizer

A collection of pulseaudio visualizers written in rust (and python)
Rust
17
star
10

pavu-mixer

"Hardware Mixer" for PulseAudio
Rust
13
star
11

Poppy-Logic-Controller

A budget PLC-like board for controlling 24V DC equipment.
Rust
13
star
12

profirust

A PROFIBUS-DP compatible communication stack written in Rust
Rust
10
star
13

atmega32u4

Low level access to ATmega32U4 registers in Rust
Rust
10
star
14

arduino-leonardo

Board Support Crate for Arduino Leonardo in Rust
Rust
5
star
15

leonardo-examples

Arduino Leonardo Examples in Rust
Rust
5
star
16

eagre-asn1

A Rust asn1 library
Rust
4
star
17

atmega32u4-hal

Hardware Abstraction Layer for ATmega32U4
Rust
3
star
18

blog-theme

Theme for my personal blog
Sass
3
star
19

Julia3D

Julia sets visualized in 3d using webgl
JavaScript
3
star
20

Alien-Invaders

This is a tower defense game where you have to protect your base against incoming UFOs. The game is written in Javascript and playable in every Web-Browser.
JavaScript
2
star
21

eagre-ecs

A Rust entity-component system
Rust
1
star
22

i2c-proxy-demo

Demo of a proxy for multiple devices on the same bus
Rust
1
star
23

frequency-bands

E-UTRA frequency bands cheatsheet
HTML
1
star
24

tf2-voicelines

A website that aims to be a quick way to find Team Fortress 2 quotes
HTML
1
star
25

elite-panel

elite-panel is a side panel/companion for Elite Dangerous.
JavaScript
1
star
26

DummyProject

A MMO that is played in browser
1
star
27

coriolis-sim

Simulating a coriolis station from Elite: Dangerous and its problems
Rust
1
star