Open Nemo157 opened 6 years ago
And finally got round to using this on some real hardware, it works perfectly (although, integrating task notification into HAL layers without impacting non-futures
use of them is stil an issue).
Thanks @Nemo157 for taking on this work! I strongly agree with your overall goals.
I'd really like to see if we can somehow finagle io::Error
to work in core
as a general solution to this problem. I will push on that with the libs team.
Is there any blockers on this? I really wish there is some Read
/Write
traits accepted by the ecosystem (especially async). Otherwise most of the no_std
bail out to core::fmt::Write
, which is limited by str
constrains or make their own traits.
Also since 0.3 picks up some nightly features (pin
and arbitrary_self_types
) maybe we should also use associated_type_defaults
instead of supertrait approach, making default error type std::io::Error
if std
feature enabled, so that we don't introduce 2 traits for the same thing, making documentation and implementation on top of this traits much cleaner.
It would be really awesome if you could somehow write your embedded code as async functions, and then have some clever executor setup the necessary interrupts and call wfi
when there's nothing to do. You could possibly end up with code as good (for power usage) as hand-written but with all the embedded details abstracted. Would be very cool.
I don't believe this is something we'll be able to tackle without support from upstream, since I think it's important that these traits mirror the upstream std::io::Read/Write
counterparts. I'm open to suggestions here, though, if anyone has ideas about how to avoid this restriction!
@cramertj Not everything can be implemented for no_std for io, but most of it can now thanks to https://github.com/jethrogb/rust-core_io.
Inspired by @Ericson2314's comment on a portability-wg issue about allocation-less
std::io::Error
I decided to attempt a two-layered approach toAsync{Read,Write}
allowing supportingno_std
targets with most of thefutures-io
andfutures-util::io
adaptors.The main change required is a second set of traits (
CoreAsync{Read,Write}
) which have an associated error type instead of usingstd::io::Error
, theAsync{Read,Write}
traits are then implemented on top of these traits whereCoreAsync{Read,Write}::Error: Into<std::io::Error>
.One difficulty is that some of the more important adaptors (e.g.
futures-util::io::ReadExact
) re-use error variants fromstd::io::Error
, my first attempt at working around this limitation is to force the underlying error type to provide at least the two variants that the adaptors require. This seems a bit messy, I'm unsure if there's a much nicer solution to this.My main goal with this was to be able to use these adaptors with types from the
embedded-hal
library for non-blocking serial connections, via thenb
library. I have an example of this compiling now, but I'll have to wait till I'm at work tomorrow to try and get it running on real hardware.Links to the changes:
futures
changesnb
changesembedded-hal
changesI'm creating this issue now to get feedback on whether this is something that might be supported by the core
futures
library at some point. I really would like to avoid splitting the ecosystem betweenstd
andno_std
Futures, e.g. I'm likely to be looking at using/building a non-blocking CoAP library, and am hoping to be able to make it work with bothstd
andno_std
environments without much effort in the library itself.