esp-idf-hal
esp-idf-hal copied to clipboard
serial: Add support for interrupts and variable RX/TX buffer size
This PR adds support for interrupt-driven workflow for UARTs and adjusting RX/TX buffer size from the user facing config struct.
This allows notably to create tasks that can wait indefinitely for RX data without having to poll continuously, and a first step towards DMA support.
This is my first contribution on esp-idf-hal, so a thorough review would be welcome.
One particular point of attention is for EventStruct which manually implements Send. I'm not really sure if that's the good way to wrap the event handle allocated from IDF, and maybe wrapping it up in a mutex could be safer there.
Those modifications break usage without event handler, I'm investigating...
I'm reacting in a bit late here and that might be totally off, but here's a very different suggestion, that I've mentioned a few times in the past: why not implementing a blocking API, where you can pass a whole buf that can be read?
I'm reacting in a bit late here and that might be totally off, but here's a very different suggestion, that I've mentioned a few times in the past: why not implementing a blocking API, where you can pass a whole buf that can be read?
Yeah, I'm very much in support of this. In fact, my fork has a branch with an ad-hoc impl of this, as I couldn't get away without it. Happy to clean it up and PR at some point.
Folks, now that I've merged #115, I think we have a simple solution (blocking reads) which should work fine with regular code that uses threads. Also - and if I interpret the documentation if ESP-IDF correctly - writes are already blocking, as they use uart_write which is a blocking function.
While I agree that ideally we need nonblocking APIs as well, the current nb based ones are less than ideal for a multitude of reasons (do not compose well, require busy looping, e-hal itself is moving to a true async model instead etc.).
So what I would suggest - instead of using queues, exposing uart interrupts etc - we should just embrace the true Rust async model for nonblocking APIs, ala embedded-hal-async.
Given that embedded-hal-async still does not have async (GAT) traits for serial, we should either wait for those, or if someone has a pressing need for truly async uart - expose struct-based ESP-IDF async API in the meantime.
After switching from my branch to the last release, blocking read seems to be working well enough (~3% less throughput on my OTA over UART transfer) for my application. I'd still like to have access to interrupt-driven code in general (and no RTOS, but that's not the target of this HAL), but I think we can close this PR until we have a proper model for implementing such thing globally.