Git Product home page Git Product logo

shared-bus's Introduction

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.

shared-bus's People

Contributors

dependabot[bot] avatar dylan-dpc avatar gazedo avatar geomatsi avatar jscatena88 avatar pyaillet avatar rahix avatar regexident avatar rursprung avatar ryan-summers avatar ryankurte avatar taks avatar thejpster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shared-bus's Issues

Errors using shared-bus with ESP32 (esp_idf_hal and bme280-rs)

I am trying to use shared-bus with ESP32 using esp_idf_hal and bme280-rs.
If I don't use shared-bus I have no problems using bme280.

Code with problems

use esp_idf_hal::delay;
use esp_idf_hal::i2c;
use esp_idf_hal::prelude::*;
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported

use log::*;

use bme280::i2c::BME280;

fn main() {
    esp_idf_sys::link_patches();
    
    // Bind the log crate to the ESP Logging facilities
    esp_idf_svc::log::EspLogger::initialize_default();

    let peripherals = Peripherals::take().unwrap();
    let pins = peripherals.pins;

    // Create i2c interface on I2C0 with bus speed of 400kHz
    let i2c0 = peripherals.i2c0;
    let scl = pins.gpio22;
    let sda = pins.gpio21;
    let i2c_config = <i2c::config::MasterConfig as Default>::default().baudrate(400.kHz().into());

    let i2c_bus_0 = i2c::Master::<i2c::I2C0, _, _>::new(i2c0, i2c::MasterPins { sda, scl }, i2c_config).unwrap();

    let i2c_bus_manager = shared_bus::BusManagerSimple::new(i2c_bus_0);

    let mut i2c_bme280 = BME280::new_primary(i2c_bus_manager.acquire_i2c());  <-----ERROR HERE
    //let mut i2c_bme280 = BME280::new_primary(i2c_bus_0);  <---- This works fine no ERRORS when not using shared-bus
    
    let mut delay = delay::Ets;
    i2c_bme280.init(&mut delay).unwrap();    <---ERROR HERE

Errors

error[E0277]: the trait bound `I2cProxy<'_, NullMutex<esp_idf_hal::i2c::Master<I2C0, esp_idf_hal::gpio::Gpio21<esp_idf_hal::gpio::Unknown>, esp_idf_hal::gpio::Gpio22<esp_idf_hal::gpio::Unknown>>>>: embedded_hal::i2c::blocking::I2c` is not satisfied
  --> src/main.rs:46:46
   |
46 |     let mut i2c_bme280 = BME280::new_primary(i2c_bus_manager.acquire_i2c());
   |                          ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `embedded_hal::i2c::blocking::I2c` is not implemented for `I2cProxy<'_, NullMutex<esp_idf_hal::i2c::Master<I2C0, esp_idf_hal::gpio::Gpio21<esp_idf_hal::gpio::Unknown>, esp_idf_hal::gpio::Gpio22<esp_idf_hal::gpio::Unknown>>>>`
   |                          |
   |                          required by a bound introduced by this call
   |
note: required by a bound in `bme280::i2c::BME280::<I2C>::new_primary`
  --> /home/ed/rust-crates/bme280-rs/src/i2c.rs:22:10
   |
22 |     I2C: I2c + ErrorType,
   |          ^^^ required by this bound in `bme280::i2c::BME280::<I2C>::new_primary`

error[E0599]: the method `init` exists for struct `bme280::i2c::BME280<I2cProxy<'_, NullMutex<esp_idf_hal::i2c::Master<I2C0, esp_idf_hal::gpio::Gpio21<esp_idf_hal::gpio::Unknown>, esp_idf_hal::gpio::Gpio22<esp_idf_hal::gpio::Unknown>>>>>`, but its trait bounds were not satisfied
  --> src/main.rs:49:16
   |
49 |     i2c_bme280.init(&mut delay).unwrap();
   |                ^^^^ method cannot be called on `bme280::i2c::BME280<I2cProxy<'_, NullMutex<esp_idf_hal::i2c::Master<I2C0, esp_idf_hal::gpio::Gpio21<esp_idf_hal::gpio::Unknown>, esp_idf_hal::gpio::Gpio22<esp_idf_hal::gpio::Unknown>>>>>` due to unsatisfied trait bounds
   |
  ::: /home/ed/.cargo/registry/src/github.com-1ecc6299db9ec823/shared-bus-0.2.3/src/proxies.rs:15:1
   |
15 | pub struct I2cProxy<'a, M> {
   | --------------------------
   | |
   | doesn't satisfy `_: embedded_hal::i2c::ErrorType`
   | doesn't satisfy `_: embedded_hal::i2c::blocking::I2c`
   |
   = note: the following trait bounds were not satisfied:
           `I2cProxy<'_, NullMutex<esp_idf_hal::i2c::Master<I2C0, esp_idf_hal::gpio::Gpio21<esp_idf_hal::gpio::Unknown>, esp_idf_hal::gpio::Gpio22<esp_idf_hal::gpio::Unknown>>>>: embedded_hal::i2c::blocking::I2c`
           `I2cProxy<'_, NullMutex<esp_idf_hal::i2c::Master<I2C0, esp_idf_hal::gpio::Gpio21<esp_idf_hal::gpio::Unknown>, esp_idf_hal::gpio::Gpio22<esp_idf_hal::gpio::Unknown>>>>: embedded_hal::i2c::ErrorType`

How can I make shared-bus work with esp_idf_hal and bme280-rs?

Is it possible to use this library with RTIC?

Hi there,

I'm a visitor from rust-embedded/embedded-hal#35 :) I'm currently trying to use shared-bus in an RTFM project and am trying to late-initialise peripherals. I can't quite get it to work when using shared-bus, however, because the initial BusManager either goes out of scope at the end of the init method, or gets moved into init::LateResources, and therefore I can't figure out how to annotate the lifetime of the BusProxy. Here's a small-ish example:

//! examples/init.rs

#![deny(unsafe_code)]
#![no_main]
#![no_std]

extern crate panic_semihosting;

use stm32f0::stm32f0x0::I2C1;

use stm32f0xx_hal::{
    i2c::I2c,
    prelude::*,
    gpio,
    gpio::{
        Alternate,
        gpiob,
    },
};

use rtfm::app;

use shared_bus::BusManager;
use ssd1306::Builder;
use ssd1306::prelude::*;
use embedded_graphics::prelude::*;

type I2C1Bus = I2c<I2C1, gpiob::PB8<Alternate<gpio::AF1>>, gpiob::PB9<Alternate<gpio::AF1>>>;

#[app(device = stm32f0::stm32f0x0)]
const APP: () = {
    static mut I2C_BUS: BusManager<
        cortex_m::interrupt::Mutex<core::cell::RefCell<I2C1Bus>>, I2C1Bus> = ();
    static mut DISPLAY: ssd1306::mode::graphics::GraphicsMode<
        ssd1306::interface::i2c::I2cInterface<
            shared_bus::proxy::BusProxy<
                '_,  // this lifetime parameter is the one I can't figure out.
                cortex_m::interrupt::Mutex<core::cell::RefCell<I2C1Bus>>,
                I2C1Bus>>> = ();

    #[init]
    fn init() -> init::LateResources {
        let dp = device;

        let mut flash = dp.FLASH;
        let mut rcc = dp.RCC.configure().freeze(&mut flash);
        let gpiob = dp.GPIOB.split(&mut rcc);

        // Configure i2C pins
        let (scl, sda) = cortex_m::interrupt::free(|token| {
            (
                gpiob.pb8.into_alternate_af1(token),
                gpiob.pb9.into_alternate_af1(token),
            )
        });
        let i2c = I2c::i2c1(dp.I2C1, (scl, sda), 400.khz(), &mut rcc);
        let bus = BusManager::<cortex_m::interrupt::Mutex<_>, _>::new(i2c);

        let mut disp: GraphicsMode<_> = Builder::new().connect_i2c(bus.acquire()).into();

        init::LateResources {
            I2C_BUS: bus,
            DISPLAY: disp,
        }
    }
};

My questions are:

  • is it possible to initialise i2c devices using SharedBus in the #[init] method of an RTFM application?
  • if not, is this something that you'd be open to design ideas / pull requests for?

Also, I can't figure out if this is more an issue on the RTFM side or on the shared-bus side - I suspect that it's a limitation intrinsic to the way resources are initialised with RTFM. I'm still new to rust; please let me know if this seems like something I should be raising over there instead.

Thanks in advance.

Support for platforms without atomics?

$ cargo check --target thumbv6m-none-eabi
    Checking shared-bus-rtic v0.2.1 (https://github.com/ryan-summers/shared-bus-rtic?branch=feature/spi-full-duplex#fad95b37)
error[E0599]: no method named `compare_exchange` found for struct `core::sync::atomic::AtomicBool` in the current scope
  --> /Users/bwstitt/.cargo/git/checkouts/shared-bus-rtic-b510fcc9e8973e1f/fad95b3/src/lib.rs:73:14
   |
73 |             .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
   |              ^^^^^^^^^^^^^^^^ method not found in `core::sync::atomic::AtomicBool`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `shared-bus-rtic`.

To learn more, run the command again with --verbose.

I'm not sure there's any way to "fix" this. I think it might just be better to say that thumbv6m-none-eabi and other platforms without atomics are not supported.

I'm going to use a platform with thumbv7m-none-eabi instead of the feather_m0 that I was planning on using since atomics are going to be helpful for a few things.

Compile errors platforms without `critical-section` support (was: Support Arduino?)

I'm using arduino-hal and shared-bus to manage two devices on the same i2c bus. Is this supported? Am I doing something wrong? When compiling I get:

   Compiling critical-section v0.2.5
error: Critical section is not implemented for this target. Make sure you've specified the correct --target. You may need to supply a custom critical section implementation with the `custom-impl` feature
   --> /home/laura/.cargo/registry/src/github.com-1ecc6299db9ec823/critical-section-0.2.5/src/lib.rs:149:9
    |
149 | ...   compile_error!("Critical section is not implemented for this target. Make sure you've specified the correct --target. You may need to supply a custom critical section implementation with the `custom-impl` feature");
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: could not compile `critical-section`

0.1.3 is not compatible with 0.1.2 for `no_std`

0.1.3 contains a breaking change because it requires additional options in crates pulling it in to compile for no_std due to the use of embedded-hal-mock:

    Updating crates.io index
   Compiling embedded-hal-mock v0.4.0
error[E0463]: can't find crate for `std`
  |
  = note: the `thumbv6m-none-eabi` target may not be installed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: Could not compile `embedded-hal-mock`.

To learn more, run the command again with --verbose.

method not found in `AtomicBool`

(Related to #4 and #17.)
Using shared-bus v0.2.0 I have several examples building on several device HALs but with stm32f0xx I have a problem with .compare_exchange. (Also happening with git shared-bus #0f429435.)

Compiling shared-bus v0.2.2 (https://github.com/Rahix/shared-bus#0f429435)
error[E0599]: no method named `compare_exchange` found for struct `AtomicBool` in the current scope
   --> /home/paul/.cargo/git/checkouts/shared-bus-afeeec54cdff0f33/0f42943/src/mutex.rs:208:14
    |
208 |             .compare_exchange(
    |              ^^^^^^^^^^^^^^^^ method not found in `AtomicBool`

CI with examples working on other device HALs is at https://github.com/pdgilbert/rust-integration-testing/runs/4998981227?check_suite_focus=true. (stm32f030 is a job at the bottom.)

Roadmap

The current version is still pretty much what I drafted up initially. The design has shown a few flaws over time, which should be addressed in a new version. Here is an overview:

  • The SPI proxy is unsound when shared across multiple tasks. This is because the CS pin is handled outside the proxy. Ref. #8
  • More existing mutexes should be supported out of the box. E.g. anything implementing lock-api. Ref. #9
  • If I'm not mistaken, sharing in a single execution context (!Send) can be done with even less overhead than the current NullMutex. This should be explored.
  • A macro should be added for pushing the bus-manager into a static mut, thus giving the references a &'static lifetime which makes sharing between tasks much easier. Ref. #13
  • Try to reduce type-signature sizes with type aliases as much as possible. Because statics require full signatures, it would be great to keep their length as small as possible.
  • Support for AVR.
  • Support for RISC-V (see this fork).

Can bus suppport?

Is there anything that would prevent adding support for can bus? If not and this would be a welcome addition I'll plan to start working on it as it would be useful in my own project(s).

Could not find xtensa_lx6 with no_std

I'm running into the following issue:

error[E0433]: failed to resolve: could not find `xtensa_lx6` in `$crate`
   --> src/main.rs:109:9
    |
109 |         shared_bus::new_xtensa!(i2c::Master<i2c::I2C0, Gpio21<Unknown>, Gpio22<Unknown>> = i2c)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not find `xtensa_lx6` in `$crate`
    |
    = note: this error originates in the macro `shared_bus::new_xtensa` (in Nightly builds, run with -Z macro-backtrace for more info)

Am I missing an import or something? I've tried the following:

shared-bus = { git = "https://github.com/Rahix/shared-bus.git", features = ["xtensa"] }
shared-bus = { version = "0.2.4", default-feature = false, features = ["xtensa"] }
shared-bus = { version = "0.2.2", default-feature = false, features = ["xtensa"] }
shared-bus = { version = "0.2.0", default-feature = false, features = ["xtensa"] }

with one of the following:

xtensa-lx = { version = "0.6.0", features = ["esp32"] }
xtensa-lx-rt = { version = "0.13.0", features = ["esp32"] }
xtensa-lx6 = { version = "0.2.0" }

Thats the line that worked back when the app was std with the new_std! macro and I don't think I'm calling it incorrectly, this is the code I'm using:

let i2c = i2c::Master::new(i2c0, i2c::MasterPins { sda, scl }, config).unwrap();
let bus: &'static _ = shared_bus::new_xtensa!(i2c::Master<i2c::I2C0, Gpio21<Unknown>, Gpio22<Unknown>> = i2c).unwrap();

SpiProxy is still unsound, even in a single thread

The "fix" for #8 assumes that drivers will only activate their CS right before communicating and deactivate it right afterwards and that there is no way for any other code in the same thread to do anything else in that time. However, this is not part of any API contract and drivers don't always work this way in practice.

The following hypothetical driver is perfectly valid, but using it with SpiProxy would lead to some unfortunate bugs.

pub struct DoomsdayDevice<SPI, CS> {
    spi: SPI,
    cs: CS,
}

impl<SPI, CS> DoomsdayDevice<SPI, CS>
where
    SPI: embedded_hal::blocking::spi::Write<u8>,
    CS: embedded_hal::digital::v2::OutputPin,
    CS::Error: core::fmt::Debug,
{
    pub fn new(spi: SPI, mut cs: CS) -> Self {
        // We own the SPI struct, so it is fine to just keep the CS pin active (low)
        cs.set_low().unwrap();
        Self { spi, cs }
    }

    pub fn detonate(&mut self) -> Result<(), SPI::Error> {
        // Send the super-secure password to the device, ending all life on earth
        self.spi.write(&[0x00])
    }

    pub fn split(self) -> (SPI, CS) {
        let Self { spi, mut cs } = self;
        // Set the CS pin to idle (high)
        cs.set_high().unwrap();
        (spi, cs)
    }
}

For my suggestion about how to fix this problem, see rust-embedded/embedded-hal#299

Compilation error: could not find `OneShot` in `adc`

Using: shared-bus= { version="=0.2.3", features = ["std"] } results in compilation errors (ARM)

Log


error[E0433]: failed to resolve: could not find `OneShot` in `adc`
   --> /.cargo/registry/src/github.com-1ecc6299db9ec823/shared-bus-0.2.3/src/proxies.rs:146:34
    |
146 |     type Error = <M::Bus as adc::OneShot<ADC, Word, Pin>>::Error;
    |                                  ^^^^^^^ could not find `OneShot` in `adc`

error[E0405]: cannot find trait `OneShot` in module `adc`
   --> /.cargo/registry/src/github.com-1ecc6299db9ec823/shared-bus-0.2.3/src/proxies.rs:141:51
    |
141 | impl<'a, M: crate::BusMutex, ADC, Word, Pin> adc::OneShot<ADC, Word, Pin> for AdcProxy<'a, M>
    |                                                   ^^^^^^^ not found in `adc`

error[E0405]: cannot find trait `Channel` in module `adc`
   --> /.cargo/registry/src/github.com-1ecc6299db9ec823/shared-bus-0.2.3/src/proxies.rs:143:15
    |
143 |     Pin: adc::Channel<ADC>,
    |               ^^^^^^^ not found in `adc`

error[E0405]: cannot find trait `OneShot` in module `adc`
   --> /.cargo/registry/src/github.com-1ecc6299db9ec823/shared-bus-0.2.3/src/proxies.rs:144:18
    |
144 |     M::Bus: adc::OneShot<ADC, Word, Pin>,
    |                  ^^^^^^^ not found in `adc`

Some errors have detailed explanations: E0405, E0433.
For more information about an error, try `rustc --explain E0405`.
error: could not compile `shared-bus` due to 4 previous errors

Using shared-bus= { version="=0.2.2", features = ["std"] } works as expected. Is this a regression or is ARM not supported (anymore)?

Question about the origin of the problem

I think I see the goal of this crate: device drivers take an I2C object by value to use it. But an I2C bus can have several peripherals attached. Thus you need this to share the I2C bus between the drivers.

But the real solution should no be that the driver take a &mut I2C on the method it need, without taking ownership of the bus? Is there some patterns that can't work like that? Is there some pattern that would not be possible with shared-bus, but possible with taking a &mut I2C?

Inherent race condition when using SPI

SPI uses chip select lines to select which chip to talk to but this crate only synchronizes the SPI data transaction itself, not the chip select lines, so there's a possible race condition where a transaction occurs with multiple chip select lines asserted. I was bitten by this in an actual project, and had to revert to manually synchronizing everything.

The way to do chip select lines with embedded-hal seems to be to just pass them to drivers separately from the SPI peripheral, so there is no real way to synchronize access via just the SPI trait. The only idea I had was to add a method like BusManager::acquire_spi(cs_pin) which takes ownership of the chip select OutputPin, and returns you both a BusProxy as well as a wrapper for the chip select pin, and the wrapper actually does the locking (lock when chip select is asserted). This sounds incredibly hacky though, and I think the correct solution would be to expand the embedded-hal SPI traits to include chip select support. I think some peripherals with hardware chip selects might benefit from it anyways.

SpiProxy does not implement FullDuplex trait

Hello,
I stumbled upon the issue of bus sharing among device structs and I was trying to use shared-bus to solve it.
Although it looks very promising I was stopped immediately be the fact that SpiProxy does not emplement the embedded_hal::spi::FullDuplex trait, which I need to use [embedded_sdmmc](https://docs.rs/embedded-sdmmc/0.3.0/embedded_sdmmc/struct.SdMmcSpi.html).

I was wondering if there is a particular reason for this missing implementation, if it's scheduled for a later date (I couldn't find it in the roadmap) or if it was simply missed (the FullDuplex trait is in a different module from embedded_hal::blocking::spi::{Write, Transfer}, which are actually implemented).

Errors compiling for ESP32 std

Hello!

I've recently taken a dive into the embedded rust world and have run across a problem. I have cloned this repo https://github.com/ivmarkov/rust-esp32-std-demo and gotten it running on my ESP32-C3-M1 using nightly. However, when I add this dependency I get a compilation error.

 RUST_BACKTRACE=1 cargo build
   Compiling riscv v0.7.0
error: failed to run custom build command for `riscv v0.7.0`

Caused by:
  process didn't exit successfully: `./target/debug/build/riscv-6960dc4cd1ce77dc/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/riscv-0.7.0/build.rs:22:10
  stack backtrace:
     0: rust_begin_unwind
               at /rustc/cb121987158d69bb894ba1bcc21dc45d1e0a488f/library/std/src/panicking.rs:584:5
     1: core::panicking::panic_fmt
               at /rustc/cb121987158d69bb894ba1bcc21dc45d1e0a488f/library/core/src/panicking.rs:142:14
     2: core::result::unwrap_failed
               at /rustc/cb121987158d69bb894ba1bcc21dc45d1e0a488f/library/core/src/result.rs:1785:5
     3: core::result::Result<T,E>::unwrap
               at /rustc/cb121987158d69bb894ba1bcc21dc45d1e0a488f/library/core/src/result.rs:1078:23
     4: build_script_build::main
               at ./build.rs:18:9
     5: core::ops::function::FnOnce::call_once
               at /rustc/cb121987158d69bb894ba1bcc21dc45d1e0a488f/library/core/src/ops/function.rs:248:5
  note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

I realize this library doesn't support riscv yet, however I thought since std is available that it would work anyway.

[dependencies]
shared-bus = { version = '0.2.3', features = ['std'], default-features = false }

Is this possible with a config change? My rust knowledge is very limited at this point.

Implement embedded_hal::i2c::I2c for I2C proxies

Would it be possible to implement embedded_hal::i2c::I2c for the I2C proxy types? I'm using a driver crate for the bme280 sensor that depends on this this trait so it currently cannot be used together with shared-bus.

How to embed this (resolving lifetime constraints)

hey so, i'm trying to embed a BusManager and a set of drivers consuming i2c::Write etc. into an object but, finding it extremely difficult to resolve the lifetime requirements to do so as the reference to the BusManager must outlive the BusProxy objects.

it appears this is a reflection of the use of Mutex<RefCell<_>> rather than the more common Arc<Mutex<_>>, and i see why this approach has been taken, just wondering if you have any ideas about how to make it possible?

Esp32 with I2C using BusManagerStd for threads

I got lost on your example for using shared-bus with threads.

My cargo.toml file in [dependencies]

shared-bus = {git = "https://github.com/Rahix/shared-bus.git", version = "0.2.3", features = ["eh-alpha", "std"]}

My main.rs

    let peripherals = Peripherals::take().unwrap();
    let pins = peripherals.pins;

    // Create i2c interface on I2C0 with bus speed of 400kHz
    let i2c0 = peripherals.i2c0;
    let scl = pins.gpio22;
    let sda = pins.gpio21;
    let i2c_config = <i2c::config::MasterConfig as Default>::default().baudrate(400.kHz().into());
    let i2c_bus_0 =
        i2c::Master::<i2c::I2C0, _, _>::new(i2c0, i2c::MasterPins { sda, scl }, i2c_config)
            .unwrap();

    // Create a shared-bus for the I2C devices
    let i2c_bus_manager: &'static _ = shared_bus::new_std!(i2c_bus_0).unwrap();  <-------- ERROR IS HERE

My error

expected 1 argument, found 0
unexpected end of macro invocation
missing tokens in macro arguments

1. Sorry I am new to rust, what needs to be done to get rid of the error.
2. I tried xtensa feature but that failed with " cannot find macro llvm_asm in this scope"

What kind of shared bus should I use?

I have already wrapped my peripherals with Arc and Mutex, like this:

pub struct AppPeripherals<'a> {
    pub sht31: Arc<Mutex<...>>,
    pub max17048: Arc<Mutex<...>>,
}

(The peripherals will be shared across multiple threads.)
What kind of shared bus should I use? BusManagerSimple or BusMutex?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.