2024-02-06 05:15 AM
The system consists of three modules: a 4G module, a GNSS module, and an STM32 processor, with the modules connected to the STM32 via UART. In terms of program functionality, the STM32 needs to implement data forwarding and saving. It receives data from the GNSS module, forwards it to the 4G module while creating a copy to save on the SD card; it also receives data from the 4G module, forwards it to the GNSS module while creating a copy to save on the SD card as well.
To achieve the above logic, I have used UART DMA、Ringbuf and Free-RTOS. UART DMA is set to DMA circular reception mode with HT, TC, and UART IDLE interrupt enabled. Data is first transferred to a fixed DMA Buff through DMA, then manually moved to Ringbuf in the callback function. In the processing function, data from Ringbuf is moved to the SD Ringbuf and to the sending Ringbuf. Corresponding operations, such as SD card writing and DMA sending, are executed in their respective threads.
This is roughly the framework of my code, which meets my requirements. I wonder if there's a better framework for forwarding UART data, allowing for more direct UART1 RX -> UART2 TX forwarding, and optimizing the whole process.
My question is, in the mentioned routine, if UART1 and UART2 have the same baud rate, and if UART1 is receiving data at full load, UART2's transmission experiences packet loss. I'm not sure where this problem occurs. Could there be a DMA conflict? Is it impossible for the same DMA bus to handle full-rate receiving and sending simultaneously? Also, in this scenario, should I use UART DMA FIFO? How should it be used?
Solved! Go to Solution.
2024-02-06 06:08 AM
There are two possible sources of problems.
1. Your software "architecture" - I'm not going to discuss this. DMA is certainly capable of transferring whatever data are on UART even without FIFO; but the IDLE mechanism, RTOS, SD card handling, all this sounds like there may be potential corner cases lurking. But it's software error, whether a simple bug or some involved case. It can be eliminated at least for experiments by getting rid of the whole shebang and writing the simplest possible polled implementation.
2. There's a fundamental problem with "forwarding" data between UARTs set to the same baudrate, and that's namely the baudrate mismatch together with the principial tolerance of UART to it. Let's assume the most usual case of 8N1, then a byte's transmission time is 10 bit periods. However the receiver is tolerant to a mismatch so that if the transmitter is slightly faster, it still can receive the bytes correctly. This tolerance is roughly half a bit per the whole frame (i.e. if transmitter succeeds to finish the whole 8N1 frame and starts the next frame just after half of the receiver's bit-counter's stopbit, receiver still receives all the bytes successfully). So, in terms of the "forwarder's" baudrate, the primary transmitter can transmit a byte in 9.5 bit's time, but the receiver "forwards" data to its transmitter and that takes exactly 10 bit's time to transmit a byte. In other words, in worst case, 21 bytes can arrive at receiver while it can transmit 20 bytes. If the data stream is uninterrupted, at one point FIFOs are exhausted and data are dropped.
There's no magic remedy for this issue; workarounds have to stem from the particularities of given application. The forwarding transmitter can to be set to higher baudrate but timing has to be carefully calculated so that the secondary receiver won't start to drop data because of baudrate mismatch.
JW
2024-02-06 05:54 AM
> Could there be a DMA conflict?
No
> Is it impossible for the same DMA bus to handle full-rate receiving and sending simultaneously?
Yes
> Also, in this scenario, should I use UART DMA FIFO? How should it be used?
It can be used but isn't needed. UART is low-speed, there are no problems handling it without using the FIFO.
Probably the issue lies in your code logic somewhere, which we cannot see. But the core concept of receiving UART and forwarding it to another port is doable and can be accomplished in code.
2024-02-06 06:08 AM
There are two possible sources of problems.
1. Your software "architecture" - I'm not going to discuss this. DMA is certainly capable of transferring whatever data are on UART even without FIFO; but the IDLE mechanism, RTOS, SD card handling, all this sounds like there may be potential corner cases lurking. But it's software error, whether a simple bug or some involved case. It can be eliminated at least for experiments by getting rid of the whole shebang and writing the simplest possible polled implementation.
2. There's a fundamental problem with "forwarding" data between UARTs set to the same baudrate, and that's namely the baudrate mismatch together with the principial tolerance of UART to it. Let's assume the most usual case of 8N1, then a byte's transmission time is 10 bit periods. However the receiver is tolerant to a mismatch so that if the transmitter is slightly faster, it still can receive the bytes correctly. This tolerance is roughly half a bit per the whole frame (i.e. if transmitter succeeds to finish the whole 8N1 frame and starts the next frame just after half of the receiver's bit-counter's stopbit, receiver still receives all the bytes successfully). So, in terms of the "forwarder's" baudrate, the primary transmitter can transmit a byte in 9.5 bit's time, but the receiver "forwards" data to its transmitter and that takes exactly 10 bit's time to transmit a byte. In other words, in worst case, 21 bytes can arrive at receiver while it can transmit 20 bytes. If the data stream is uninterrupted, at one point FIFOs are exhausted and data are dropped.
There's no magic remedy for this issue; workarounds have to stem from the particularities of given application. The forwarding transmitter can to be set to higher baudrate but timing has to be carefully calculated so that the secondary receiver won't start to drop data because of baudrate mismatch.
JW
2024-02-06 06:56 PM
Thank you for your response. Your answer is very clear.