-
Notifications
You must be signed in to change notification settings - Fork 234
Added new (yet unproven) blocking Read trait for a rngs #45
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
Conversation
Signed-off-by: Daniel Egger <[email protected]>
I'm not immediately clear on how this is to be used, is the intention with this to block until entropy is available or return an error in the case it's not? |
Almost. The Error is meant for situations where no entropy can be generated at all, e.g. if there's not random generator or it is not available for some reason (like being used by another hardware block).
Well, if you need entropy then you often need a specific amount of it and I find it a bit inconvenient to handle such a situation with async calls other than blocking on the spot. Different platform will also yield a different numbers of bytes per round, e.g. with NRF51 you'll get 1 byte per round while the STM32s will yield 4 byte per round. If you need a larger amount of data I'd recommend setting up an interrupt handler and simply using the blocking call with the amount of data a platform will yield. Of course we still don't have any support whatsoever to properly include interrupt setup and handling in the HAL drivers so that requires some dancing around... One could certainly craft an async interface, too, but at the moment I don't see too much benefit in that. |
src/blocking/rng.rs
Outdated
//! Blocking hardware random number generator | ||
|
||
/// Blocking read | ||
pub trait Read { |
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.
This trait should be gated behind #[cfg(feature = "unproven")]
, in addition to the gate in prelude
.
At least, that's what I gather from the crate docs and the other unproven traits (like digital::InputPin
)
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.
That can certainly be done. However the rules say that a trait is proven if at least two implementations and a driver or demo application exists and that is actually already the case. 😉
The benefit I can see to an async interface is interaction with nonblocking application models, such as those based on The |
@austinglaser And where would you store the data in the meantime? The API is modelled like the other blocking APIs in that you pass in a buffer to be filled. Otherwise you can only return a single value in the result. |
Signed-off-by: Daniel Egger <[email protected]>
@therealprof That's a good point -- I hadn't thought through that aspect enough. What about a trait (eventually, and in addition to this one) which returns a fixed-size random value? That fixed-size value could be (taking a page out of the I think I favor the simple Something like this? // rng.rs
pub trait Read {
type Error;
fn read(&mut self) -> nb::Result(u8, Self::Error);
} But this is getting beyond the scope of discussion for this particular pull request, I think. |
@austinglaser A single |
@therealprof I'd say that forcing a user to block is limiting in a different way -- at the trait level, at least, it makes sense to allow both usage patterns.
You'd store the data in a context struct you pass back into the function each time. If that doesn't sound terribly ergonomic, you could use futures or generators, which do much the same thing behind the scenes but (especially in the generator case) are a little cleaner to use. |
For a semi real-world example, take a look at the docs for the nb crate. Note that the LED "thread" in each case has some mutable data ( |
Blocking on a MCU is relative anyway since you can always interrupt the wait. But sure, if you have a use case for partial random data being available whenever it shows up that an async interface can easily be added.
You're absolutely right that this is not ergonomic. ;) I'm familiar with the concepts of futures and generators in general. I'm still not sure about the use case in with a TRNG; maybe if you throw in DMA to automatically build up a pool from which you can deplete. But with a register based implementation there's very little point in having this; instead if you need large amount of data, use the TRNG to seed a PRNG and use that to generate random numbers whenever you need them. But hey, feel free to propose the non-blocking version of this trait. I'd even provide a non-blocking implementation, just for the fun of it. 😉 |
Fair enough! |
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.
LGTM but I'm wondering if we should add a clause to read
about what happens when an error in encountered. For example std::io::Read::read_exact
has this in its documentation:
If this function encounters an "end of file" before completely filling the buffer, it returns an error of the kind ErrorKind::UnexpectedEof. The contents of buf are unspecified in this case.
If any other read error is encountered then this function immediately returns. The contents of buf are unspecified in this case.
We could say something similar here: if an error is encountered the contents of buf
are unspecified.
Oh and kind of off-topic but there are a few traits that look very similar to each other and that look similar to some of the API in |
@japaric Would you like me to change the name to |
Signed-off-by: Daniel Egger <[email protected]>
56: Add nonblocking RNG trait r=therealprof a=austinglaser As discussed in #45, this is a nonblocking variant of an RNG interface. Co-authored-by: Austin Glaser <[email protected]>
Implements #38 . Identical custom trait already implemented in
nrf51-hal
crate and used inexamples (directly and to seed a PRNG) in the
microbit
crate.Signed-off-by: Daniel Egger [email protected]