-
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
serial: add ReadExact, ReadUntilIdle #349
Conversation
r? @ryankurte (rust-highfive has picked a reviewer for you, use r? to override) |
okay, so: There's 2 ways of writing a UART HAL drivers:
For example:
In both buffered and unbuffered, if you're using RTS/CTS data never gets lost. If you're not using RTS/CTS, it's super easy to lose data with unbuffered UARTs. People do use UART without RTS/CTS in practice, because out of pins in the MCU, or in a cable, or they simply forgot, or their protocol doesn't allow it (RS-485). IMO the traits have to be usable without RTS/CTS. So, the question is: are the traits for buffered or unbuffered, or both? For buffered, an "io::Read-like" trait that allows short reads works fine: For unbuffered, such "io::Read-like" trait does not work in practice. Some data arrives, the impl returns early, user code calls I don't think "allowing but not require early return" is a good solution. It'd make writing drivers harder, behavior should be consistent between all impls. So I can think of these solutions:
In my experience, buffered UART has been MUCH nicer to work with. For "AT-command-like" stuff, unbuffered is incredibly fiddly to get right. You often have to do "read until newline", where you don't know how many bytes it'll be. If you use RTS/CTS you can get away with reading bytes one by one, but that's slow: there's big pauses between bytes, since RTS gets toggled for each one. If you don't have RTS/CTS, there's no way to do it reliably at all. Unbuffered read is only usable for "packet-like" comms where you either know the length upfront or use "read until idle", and ideally only with CRCs/acks/retries. The downside for buffered is it requires more RAM (for the buffer), and it's much harder to impl for HALs (only sane way is to use DMA, really). So... I don't know what's best! 😅 Speaking of "io-like" traits, if we pick that option maybe we should have a set of "general" IO traits instead, and have Serial use the io traits, instead of having Serial-specific traits. This'd allow running the same code (an interactive shell maybe?) over serial and, say, a TCP connection, for example! I've been working on a set of IO traits here (because I need them for Embassy) . I think this might be starting to get out of scope for embedded-hal though. Also, this applies to both blocking and async UART read. IMO we should decide on some solution, then add it in both blocking and async forms. Not having blocking UART read is not very nice. cc @lulf |
good summary!
agreed, and i think this is the right level of abstraction for the majority of drivers (as well as being implied by the existing
i think if you need this you're going to have to implement it for your hardware anyway, so while we could provide some kind of a |
Hi, My personal opinion would be to allow as much use case as possible and let the user choose what is best for him. I guess we need:
I would be happy to help if needed. |
I also think we need the 3, yes. Note that io-like traits already exist at @ryankurte @eldruin My proposal to unblock this:
|
That sounds fine to me. I have not been deeply involved in the discussion, though. |
Hi, |
Okay, following the previous discussions:
Should be ready for review. |
442: async/serial: add Write. r=eldruin a=Dirbaio Extracted out of #349 This is just `Write`, mirroring the blocking version. so it should hopefully be uncontroversial. Co-authored-by: Dario Nieuwenhuis <[email protected]>
Discussed in today's WG meeting https://matrix.to/#/!BHcierreUuwCMxVqOf:matrix.org/$36Ghk5FUs3y2c-2eoOZKugKx4sS_xJ6VE8uS_78EyrE?via=matrix.org&via=psion.agg.io&via=tchncs.de Discussed what exactly are the differences between buffered and unbuffered, and whether we need both. No conclusions reached. |
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.
we've needed this for a long time and it seems broadly right to me so, let's see how it shakes out / lgtm ^_^
(though again it would be great to have example impls in a couple hals / a driver)
|
Rebased to fix conflicts. Could you take a look @ryankurte @eldruin @therealprof ? |
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 seems fine to me.
Let's continue the discussion about whether buffered/unbuffered is the right distinction and wording, though.
In my opinion buffered and unbuffered describe exactly what is happening under the hood and are therefore a perfect fit. |
After discussions in the WG meetings, we decided it's better to not have traits for unbuffered UART.
Next steps:
|
REQUIRES #442
Write
mirrors the blocking trait.Read
is new.Unresolved issue: how doesRead
work. See previous thread #334 (comment)