Computing > Programming

Optimizing UART (for example) output...

(1/5) > >>

Has anyone ever implemented a sort-of "Nagelized" UART driver?  Essentially, interrupt driven FIFO IO, unless the FIFO fills up, and then start DMA instead...  Because starting up DMA is pretty expensive for short outputs, but starts to make more sense the more output there is...
Maybe it'd be overly complicated.

I can't say that I have.

It seems like an odd and complicated mode switch and one that has perhaps not always significant benefit.

Is your particular UART and DMA implementation so deficient that you can't just always configure / use DMA but
have the DMA auto-triggered by the data-ready status indication of the UART?  Yeah typically it'd run for every byte but
does it really matter?

I guess what they should have is UARTs with DMA triggers set up so that the DMA could be set up to trigger either on
FIFO rx buffer high water mark or any single byte "data ready" but after a programmable inter-character time-out so you could have it accumulate a FIFO chunk of data if bytes were coming in streaming relatively continually at a high rate, but would transfer any single received byte to the
DMA output buffer and trigger a DMA service request interrupt if another character hadn't been received after time X so that the byte reception would have controlled maximum latency.

Of course that'd only really be useful for a byte oriented protocol.  If you could just program the UART DMA to trigger on either high water FIFO level or on end of packet detection (e.g. certain number of characters since start of packet detection or character pattern framing detection).

Yeah basically UART DMA / FIFO should act more like an ethernet interface in many cases where one may be transferring Mbit/s rate framed packets or something with built in framing and packet error detection hardware programmable state machine .

I meant for output.  Trying to do UART input has a whole separate (and larger) set of issues.
(I'm sorry I wasn't clearer.)


--- Quote from: westfw on July 01, 2021, 03:50:27 am ---Because starting up DMA is pretty expensive for short outputs, but starts to make more sense the
--- End quote ---

First off, are you really sure this is the case? In STM32 for example, setting up the DMA* is roughly equivalent to putting four words into the UART peripheral's FIFO back-to-back, or equivalent to sending one byte using an interrupt handler.

* Assuming you already know the previous DMA is finished and don't need to poll for completion, it's 2 to 4 memory writes depending on if you change the buffer address and size or not.

Microcontroller DMA implementations seem to be quite simple and fast to set up. Obviously, a bloated library can totally mess this up.

OTOH, if you require a timebase handler triggered by a timer for other reasons, and a suitable timer rate happens to match the UART byte rate, then managing the buffer and sending bytes in the same ISR is likely the lowest cost solution. UART TX having no failure modes like NACK, you can simply even guarantee the timing, getting rid of checking the Not Empty flag before writing to the TX data register!

I considered writing one. Aside from lines sometimes a frame of several hundred bytes would be encoded and send over uart. This frame could utilize a DMA transfer.
But I instead just optimized the uart transmit interrupt. It's so short the total effects were neglibable. Unless you're running at max baud for some reason.
But at 115200 on a STM32 of 160 Mhz the effort wouldn't yield much benefit.

When you are using the UART as block device only, then it might be worth it.

Receiving by DMA is also complicated, since you'd have to abort the DMA on the IDLE flag or a timeout and then read whatever was received. Not all DMA's support this.


[0] Message Index

[#] Next page

There was an error while thanking
Go to full version