Skip to content
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

Support for embedded and no_std #11

Closed
dhardy opened this issue Oct 19, 2017 · 12 comments
Closed

Support for embedded and no_std #11

dhardy opened this issue Oct 19, 2017 · 12 comments

Comments

@dhardy
Copy link
Owner

dhardy commented Oct 19, 2017

I am not an expert (contributions welcome), but I believe this roughly boils down to:

  • no_std implies quite a lot of functionality is unavailable
  • the error type may need to be different
  • OsRng is not available; some other entropy source is required

The above points are implied by the OS; on the hardware side:

  • The CPU may be 16-bit or even 8-bit, in which case Rng::next_u32 is not appropriate. So is it worth adding next_u16 just for these platforms? My suspicion is that anything <=16-bit probably won't use common crates like rand anyway because code-size is a major concern.
  • The CPU may not have hardware floating-point. In this case, would it use rand anyway (as above)? Would it matter that the crate contains FP code so long as it's not used?
@pitdicker
Copy link

Is there someone we should cc? Maybe @shepmaster?

@shepmaster
Copy link

I am willing to provide feedback on the things I know about, but I can't claim to know as much as might be needed. :-) I'd loop in @dylanmckay @japaric as more knowledgable people!

@dhardy dhardy added this to the rand-core RFC milestone Oct 19, 2017
@dylanmckay
Copy link

dylanmckay commented Oct 19, 2017

FWIW, as I think you've noticed is that AVR is an 8-bit target, but it does support 16-bit integers. libc::c_int is always a 16-bit integer on this platform.

32-bit and 64-bit integers are supported fine, albeit they can take up a lot of register space as arguments. It should be fine to include these kinds of functions for AVR because the linker should be able to remove any unused code, so the developer can make the choice of paying the price of a larger int type if they want. The AVR LLVM backend doesn't include bulky runtime functions to handle these types - we just emit a few consecutive additions with carry. You can generally use these types with no issue on AVR.

So far as floats go, interestingly, the AVR-GCC compiler has sizeof(float) == sizeof(double) == 4, but we do not intend to follow this convention in the avr-rust fork. AVR definitely does support floats, although I am unsure if the AVR LLVM backend generates correct code for them from memory. If it does not work properly now, the end goal would be to have 32 and 64 bit floats working in the avr-rust fork.

Including f32/f64 should be fine even on this 8-bit micro for the same reason as ints - the linker should get rid of everything unused.

@dhardy
Copy link
Owner Author

dhardy commented Oct 20, 2017

Thanks @dylanmckay. Good point about the linker removing unused code.

If AVR can handle 32-bit integers it doesn't necessarily need to use 16-bit generators, but that may still make sense for performance — so in your opinion should the rand crate support next_u16()?

@dylanmckay
Copy link

Honestly, it wouldn't be worth 16-bit generators for anything like AVR - it's pretty cheap to convert from 32 to 16-bit, and it wouldn't be worth the overhead of adding support for it IMO.

@dhardy
Copy link
Owner Author

dhardy commented Oct 22, 2017

I think this one is solved (using the error type mentioned in #10). Only remaining part is lack of OsRng but I don't think we can resolve that in general.

@japaric
Copy link

japaric commented Oct 29, 2017

I can only comment on Cortex-M microcontrollers which have 32 bit cores. Some of these micros have hardware support for random number generation (through the RNG peripheral) of 32 bit integers so next_u32 would work fine.

I do would like to mention that it would be useful to allow the implementation to be non blocking . A Error::WouldBlock would suffice I think -- we are using that approach (Error::WouldBlock can be lifted into a blocking operation, a future or a generator cf. the nb crate) with other peripherals but we haven't sketched an API for the RNG peripheral. Though this is probably more related to #10, which I have not read.

@pftbest is familiar with MSP430, which is a 16-bit architecture. Do you know if there's hardware support for random number generation on MSP430?

I suppose that if the RNG only provides 16-bit integers you could combine two generated integers into a 32 bit integer to use the Rng trait to generate a 16-bit integer (or some other 16-bit data structure that implements Rand) ... but that means waiting twice for the result which seems wasteful. And I don't think it's sensible to cast a single random 16-bit integer into a 32-bit integer when implementing Rng because that doesn't have the same entropy (?) -- I'm not a crypto person though so I don't really know.

@pftbest
Copy link

pftbest commented Oct 29, 2017

There is no dedicated hardware RNG on MSP430, as far as I know. But you can generate some random bits using Timer peripheral by correlating two independent clock sources, see http://www.ti.com/lit/an/slaa338/slaa338.pdf

As for 16/32 bit question, I can't say much. I've never used RNG on a micro-controllers, so I don't know if it's valuable to have 16bit support. I think if someone is concerned about the RNG performance they would most probably roll their own implementation instead of including a library.

@dhardy
Copy link
Owner Author

dhardy commented Oct 30, 2017

Thanks for the comments; still appears there's little demand for next_u16 then.

@japaric #9 has ErrorKind::NotReady, mostly intended for generators which need some time to initialise properly (e.g. if the OS has to collect entropy first). If this isn't sufficient we could add WouldBlock too, though it sounds like they're mostly for the same purpose ...

... but, so far there has been little call for allowing error-handling on integer functions, meaning the byte-sequence function try_fill is the only one which would actually return NotReady (other functions would retry internally or panic). See #8 and discussion on the rand-core RFC; e.g. this comment (please contribute to #8 if you disagree).

@nixpulvis
Copy link

I have a few various embedded devices, and have been following @japaric’s work a bit. If you need help testing I’m available.

@dhardy
Copy link
Owner Author

dhardy commented Nov 6, 2017

The only no_std testing I've been doing so far is cargo build --no-default-features. If you want to try implementing entropy sources (external RNGs) for bare-metal platforms or implementing 16-bit PRNG algorithms it would certainly be interesting to see, but it's beyond the scope of what I'd planned to do.

@dhardy
Copy link
Owner Author

dhardy commented Jan 22, 2018

This is now part of rand 0.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants