2015-03-06 03:35 PM
Is there a good way to implement a UART driver that uses DMA and freeRTOS? Or should I let the RXE TXNE interrupts handle the queueing and use no DMA?
It would be nice to use tha DMA to shuffle data to an array and then let the RTOS put them into a queue when possible.2015-03-07 01:44 PM
The decision to go to DMA instead of IRQs is dependent on the volume of data and the data rate. Low volume, like a console input from human typing, not much benefit. Machine to machine with large packets, definitely.
Using DMA for TX is an easy decision, do it. Unless your output is very low then using TX DMA on a USART has no down side. The overhead of TX DMA is about 1% of IRQs if you send many large blocks. And the logic in the driver is actually simpler than handling TXNE. If you are using half duplex with line turnaround just make sure you add on an IRQ to handle the TX complete interrupt after DMA completes. RX DMA is more problematic. A good design cannot assume reception of messages with an exact block size, even if the source is known. There's always a chance of noise corrupting a message as it moves through the transmission cable. So you have to be able to detect inter-message gaps to timeout RX DMA between messages. That's the basis of connecting the RXD pin to a timer input, a hardware watchdog to detect no activity for a fixed time period. (An alternative is an external retriggered one-shot, some type of 555 or variant, reset by RXD and an output trigger to an external interrupt pin.) I use a FreeRTOS based USART driver with both TX and RX DMA, half duplex RS-485 supporting several network protocols. At 460Kbits/sec the overhead is very low for messages up to 520 bytes long. The line turnaround gap at the end of every message guarantees a sufficient inter-message gap for RX DMA to work. It is somewhat complicated to build and requires a good working knowledge of async design, and especially the techniques in how to work without moving data between locations, not recommended for a beginner. But for a commercial product it definitely is a competitive advantage in that high data rates can be maintained with less hardware compared to single byte IRQ drivers. Jack Peacock2015-03-07 03:10 PM
2015-03-09 10:43 AM
2015-03-16 01:25 AM
Do you try to use IDLE interrupt? It can detect RX line is idle after reception is end.
2015-03-16 10:40 AM
The problem with IDLE is what defines end of reception. There are two parameters: inter-character gap, time between two sequential bytes; and inter-message gap; time between end of a message and start of next message. How does IDLE distinguish between the two? An idle frame is only one character so it's likely to interrupt on inter-char gaps, especially if the remote device can't stream at full speed.
If you can guarantee the remote device strictly follows timing well enough to avoid one byte gaps then yes, IDLE can be used. In practice it's not a reliable way to build a driver. Jack