-
Notifications
You must be signed in to change notification settings - Fork 7.3k
STM32: Improve speed of uart async implementation #34763
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
Comments
^^@shlomow |
We implemented our uart driver in the past with circular buffer before we used zephyr. It has some drawbacks. First, if you need hardware flow control then you have to control the rts line in software instead of hardware, and this is a little bit hard since the driver needs to know how much data the application has already read. In addition, if you want to implement the async api then you need to have a dedicated buffer in the driver, which consumes extra ram, and needs an extra memcpy from the uart driver to the application buffers. In terms of speed, I actually think that the current implementation is better, since you need an extra handling of the flow control in each interrupt (idle, half transfer, full transfer). The above is relevant only for the circular buffer implementation. As you said, when the dma controller in st has double buffer mode or linked list mode (like mdma in h7) we can easily take advantage of that and the changes in the uart driver should be minor. So to sum up, I think that the real enhancement is to |
@hjuul you mentioned enabling IRQ, you done it in application code or directly on zephyr-driver source, |
@manoj153 I did this in application code. I've scraped together some pieces of it below. As you can see it is a combination of Zephyr API and bare metal for the UART, bare metal for DMA and Zephyr API for interrupt handlers. I've since rewritten this to use Zephyr async uart API which is a lot easier, but also slower.
|
What is the state of this issue? |
@JonathanVanWin this is in our plans for this release if everything goes well (no excessive support requests aside), but not started so far. @FRASTM is out of office this week but will be back next week. You can sync with him at that time. |
@FRASTM I would be happy to work together in order to make this work. |
I too am facing the same problem. NB. No hardware flow control because of hw design constraints. |
@JonathanVanWin, sorry for late reply. Now going back to double buffer circ. mode. |
Thanks, I have since then worked on it. |
Good ! |
I actually only use one buffer. Don't use the rx_buf_rsp API. Only use the buffer given to rx_enable. |
Also, wanted to clarify, there is no need for external memcpy from application, that would be less convenient: because you have software flow control for RTS, and handle read write pointers, you can read from same buffer and process from there, and when you finished you can signal the driver. |
For reader's information: No plan to implement this in STM32 driver before an UART API update is available. |
@hjuul @cfriedt @shlomow @manoj153 @erwango Title: Intermittent Data Loss in UART Async API on STM32H753ZI (Nucleo H753ZI)
Environment: Followed Steps:
Expected Behavior: Observed Behavior:
|
Please open a dedicated issue |
@hjuul - is there a way you could also provide reproducibility information with a specific app or test in-tree? E.g. |
@cfriedt: Are you referring to my original issue or the issue recently posted by durgababu2010 in this same thread? As for my original issue it's been almost three years since I reported it; I have worked around it and moved on. But it seems from the discussion here that this issue is very well understood and has already been reproduced. |
@erwango Sorry, I can't prioritize this right now. |
I am trying to use the UART async API on stm32f7. It works nicely up to about 460.8kbps, but above that I start loosing characters during buffer switch. I immediately provide new buffers when requested, and increasing the buffer size doesn't help. So this appears to happen when new data arrives before my RX handler is done.
Describe the solution you'd like
I currently have my own implementation of this (without UART async API) where I manually configure the STM32 DMA to use circular mode and set up interrupts on Half-transfer, Transfer Complete and UART RX IDLE. It can sustain data rates far above 1Mbps even with very small buffers.
So I would like the STM32 implementation of the UART async API to use either the circular mode or the double-buffer mode of the DMA peripheral (if available). Then DMA hardware would just continue to receive UART characters regardless of how long time I spend in my RX event handler.
Additional context
I'm on Zephyr v2.5.0
The text was updated successfully, but these errors were encountered: