-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SPI/I2C keeps ref to FtInner, impossible to pass around once initialized #18
Comments
Thanks for opening an issue! Sharing a SPI bus is definitely a use-case that I want to make sure works. I'm a bit busy at work this week, but I should be able to poke around more this weekend. |
If it is easy to do so are you able to provide a minimal example of the code that fails to compile? |
IIRC sharing buses between several devices can be tricky. I used the following two crates that allow to share bus peripherals between multiple devices:
The second crate is not suitable for using with @fbeutel Could you please take a look at shared_bus and let us know if SpiProxy can help with your use-cases. Regards, |
Thanks for the replies! My use case is that we have a somewhat complex system consisting of multiple SPI buses (could be multiple FTDI devices or different SPI interfaces). I'd like to be able to configure the assignment of devices and SPI buses dynamically (via config file, etc.). Since we want to support different SPI buses on the same system, we store them in a In essence, I'd like to have something like
(complete file: https://gist.github.com/fbeutel/c8d5c974e9ed63ecfc81ef323849009c) But the last line obviously fails as In principle this could be overcome by using Arc<Mutex<...>> or something similar instead of a reference inside the SPI struct, but I understand that for most use cases you want to avoid the overhead and keep using plain references. @geomatsi Thanks for the pointer to shared_bus - I've previously looked there, but I believe that the underlying mechanism of SpiProxy works similarly and has the same problem ( |
I made a PR at #19, will that fix this issue @fbeutel ?
We are already using a Mutex, and Atomics are very lightweight, I don't anticipate any problems with this solution. |
Thanks for the efforts, and sorry for the late reply. As implemented in #19 it doesn't quite fix the issue yet, because you still store references to The fix would simply be to store an Arc directly instead of a reference to an Arc. I implemented it here (fbeutel@43c4a59), and if you like I could create a pull request. (One outstanding issue is that I cannot directly implement this solution for the |
You're right about the
Flipping the problem around: is it possible to pass this around in your code when GATs are stabilized so that you can use a generic lifetime instead of |
I'm running in to the problem where I have something simple like // src/test1.rs
use ftdi_embedded_hal as hal;
use libftd2xx::Ft4232h;
use std::sync::Arc;
pub fn open<'a>() -> Result<hal::SpiDevice<'a, Ft4232h>, Box<dyn std::error::Error>> {
let device = libftd2xx::Ft4232h::with_description("Dual RS232-HS A")?;
let hal = Arc::new(hal::FtHal::init_freq(device, 3_000_000)?);
let spi_dev = hal.spi_device(3)?;
Ok(spi_dev)
}
The problem is that spi takes a reference to hal, and I can't figure out how to make that reference live long enough so that Rust is happy. If I understand correctly it is related to this issue? Or is there a way for me to do what I want? I feel like the If I also return // src/test2.rs
use ftdi_embedded_hal as hal;
use libftd2xx::Ft4232h;
pub fn open<'a>(
) -> Result<(Box<hal::FtHal<Ft4232h>>, hal::SpiDevice<'a, Ft4232h>), Box<dyn std::error::Error>> {
let device = libftd2xx::Ft4232h::with_description("Dual RS232-HS A")?;
let hal = Box::new(hal::FtHal::init_freq(device, 3_000_000)?);
let spi_dev = hal.spi_device(3)?;
Ok((hal, spi_dev))
}
(Sorry if I'm missing something obvious, I'm still fairly new to Rust) |
You're not missing anything, there is a serious usability issue here. Thanks for commenting on this issue again, I forgot about this one! I have a PR that may fix this here: #23 I have not tested that - just quickly hacked it up on my lunch break. It compiles so it must work, right? 😆 |
As implemented currently, the
SPI
/I2C
/OutputPin
structs all keep references toMutex<RefCell<FtInner<Device>>>
.This makes it difficult / impossible to have
FtHal
inside a Box or RefCell or otherwise pass it around once SPI has been initialized.(It is possible, but then each time one would need to access the SPI functions of
FtHal
, this would require re-initializing the SPI object withSpi::new
, which is inefficient as it sends the MPSSE command each time).Would it be possible to create a shallow
Spi::new
(and accordingly for the other structs) which basically becomes a no-op if SPI has already been initialized? Or are there other ideas how one could solve this?My use case is that I need to share
FtHal
between two devices (e.g. using a shared pointer), each of which live on the Heap and need to have access to the SPI port...The text was updated successfully, but these errors were encountered: