-
Notifications
You must be signed in to change notification settings - Fork 220
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
Add ManagedCS marker trait #245
Conversation
r? @eldruin (rust_highfive has picked a reviewer for you, use r? to override) |
A managed CS addition sounds good to me in principle.
I can properly review once there is more in this PR. |
@eldruin Thanks for your write-up, so I can save my time saying pretty much the same thing. 😅 |
agreed on pretty much all points, to be clear i only meant the
my concern with this is that since
good call. in my experience (where the driver manages CS) this is usually this is implemented by the underlying driver, in this case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, thank you!
- Another alternative would be skipping e-h 1.0 support for
shared-bus
and updating only on 1.1 (which would give us more pressure to release 1.1 :), although I understand it does not look good. - Some more bikeshedding: It seems
ManagedCs
will not need to be written often, so I thinkManagedChipSelect
would be preferable.
Another (albeit far-fetched) argument for delaying stuff to 1.1 would be that we could yank version 1.1 if something is terribly wrong with it but yanking 1.0 would be more problematic.
@ryankurte: Adding the unsound SPI proxy is definitely off the table. We've seen it bite people before so it's safe to assume that it would happen again. We need a different solution here ... For the time being, we have the single-threaded SPI proxy which should be plenty for many use-cases already. For anything more complex, I'm unsure ... I think the work from @ryan-summers for shared-bus RTIC support could be a viable workaround for the time being. Essentially, it ensures safety by stuffing all bus-users into a struct and wrapping that struct in a mutex: struct SpiDevices {
pub device_a: DeviceA<SpiProxy<...>>,
pub device_b: DeviceB<SpiProxy<...>>,
}
static SPI_DEVICES: Mutex<Option<SpiDevices>> = Mutex::new(None);
fn task_a() -> Result<..., ...> {
...
SPI_DEVICES.lock(|s| {
let device_a = &mut s.ok_or(Error)?.device_a;
device_a.do_things();
})?;
}
fn task_b() -> Result<..., ...> {
...
SPI_DEVICES.lock(|s| {
let device_b = &mut s.ok_or(Error)?.device_b;
device_b.do_other_things();
})?;
} But of course, |
We discussed this in todays meeting due to the nominated flag but it's not quite clear what needs doing here. Seems like a good idea to have this to me. Can anyone summarize what we would need to discuss on the next meeting? Thanks. |
f52a0fc
to
986e589
Compare
7e6fc37
to
37083ec
Compare
updated this PR with documentation around expectations and added an implementation to Rahix/shared-bus#21, just need to update a driver to take advantage of this. the updated expectation comes down to, if you expect operations to occur in a known order you need to use in practice a bunch of drivers don't do this, primarily because last thing on the list is to update a driver / example to talk to a couple of SPI devices but, the behaviour is not something the compiler can check, so, this probably should be run but still doesn't serve as a demonstration of the negative... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great. I added some comments but it is looking good. Thanks!
src/blocking/spi.rs
Outdated
@@ -1,6 +1,9 @@ | |||
//! Blocking SPI API | |||
|
|||
/// Blocking transfer | |||
/// | |||
/// This API provides no ordering guarantees as operations can be interleaved on the bus. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't we come up with a better word to replace "ordering"? "grouping" or so, perhaps?
This still sounds to me like data from two operations could somehow be sent in the wrong order.
When reading the next sentence in the docs the user may understand that this is about grouping but still get a scare.
(for completeness: same below)
@therealprof: I had forgotten about it but I already asked about timing considerations here. I guess a crucial point would be that HALs provide both managed and non-managed CS SPI so that something like |
i think like most of the HAL this addresses the core issue but, cannot solve everything. if you have to configure timing between transactions or after CS it's going to require either device configuration or wrapping and, as you suggest, you can always implement this either in hardware or as another layer. given the generic |
These things are usually very specific when using HW. See for example how it's done in the e310x-hal We decided to expose this so users can configure the SPI in all possible ways. I don't think timings and delays should be considered in the trait abstraction level. |
3465c02
to
efb0c33
Compare
tried to update this against master, i am not sure why all those other commits have been pulled in :-/ |
a903ac4
to
7e089bc
Compare
ManagedCS indicates the CS pin is managed by the underlying driver, enabling safe bus sharing between SPI devices. SpiWithCs provides a wrapper around blocking SPI traits and an output pin to simplify use of this trait in unshared contexts.
7e089bc
to
9840fe8
Compare
closing in favour of #351 |
Per #180 this PR introduces a
ManagedCS
marker trait to indicate that theCS
line on an SPI peripheral is managed by the underlying driver. This is required to address unsoundness due to bus-sharing without explicit management of the CS pin per Rahix/shared-bus#8, and paired with #191 this will significantly improve the ergonomics of writing SPI-based drivers by no longer requiring every implementation to re-implement CS managed transactions and error handling (or to use a third party crate to do this).I have been using this approach for some time in the embedded-spi crate, for the purposes of evaluation the intent is to refactor both
embedded-spi
andshared-bus
to utilise this marker, as well as some dependent drivers (though this is for me difficult due to a cross dependency on #191).Questions
ManagedCS
interface, should this live here (in theembedded-hal
) or in a third party crate?ChipSelect
, another option isManagedChipSelect
, and other suggestions are welcome, however, please avoid adding noise to the discussion of this issue / implementation with minor naming concerns where possible.Demonstration
blocking::spi::*
trait useManagedCS
impl to shared-busaliasembedded-spi::ManagedChipSelect
toembedded_hal::blocking::spi::ManagedCs
to update allembedded
dependentsSpiWithCS
wrapper in whatever crate is appropriate (and update embedded-hal docs)I am assigning this to the v1.0 milestone though it is technically non breaking as it does effect all SPI drivers, and is somewhat critical to support use ofshared-bus
with SPI peripherals (which is no longer possible due to unsoundness with the previous impl)update: no longer part of 1.0 to avoid blocking, though hopefully to be landed shortly after thiscc. @Rahix