embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
4.91k stars 671 forks source link

STM32 - USART - Non Blocking Read #2789

Open Ralim opened 3 months ago

Ralim commented 3 months ago

Hello,

I've noticed that all of the USART drivers implement the embedded hal for read() which specifies that they should block if there is no pending data. For my current application I would be able to reduce logic complexity if I could poll these or only read the pending data rather than having to use separate tasks that may block on a read.

Would there be any room in the future to have some form of API to provide either a non-blocking read (just read out anything pending) or some way to check there is pending data (so can avoid a read if no data)?

In this context by blocking I mean both the traditional sense as well as a Future that stays pending until there is data available).

Dirbaio commented 3 months ago

BufferedUart / RingbufferedUart do exactly that, .read() immediately returns the available data without having to wait for the buffer to fill up.

Ralim commented 3 months ago

Hia,

What I'm referring to is these lines ringbuffered.read

buffered.read

Where if there is no data pending, it blocks for some data.

I'm looking for a way to read only the pending without blocking for following data.

phycrax commented 3 months ago

I think it would be possible to use poll_once for your use case.

Dillonmcewan commented 2 months ago

I ran into a similar issue. We're transitioning from a sync implementation using the stm32-rs crates. We were able to hack a solution using block_on (I'm guessing poll_once would probably also work), so we didn't block execution while waiting for data. It seems like the correct way to do this with the embedded_io traits would be to have the various USART structs implement ReadReady. That way you could do something like:

let ready = rx.read_ready()?;
if ready {
    rx.read(&mut rx_buf)?;
}