How to design a reliable solution for high-load serial communication of single-chip microcomputer?

Click on "Uncle Wheat" above and select "Top/Star Public Account"

Welfare dry goods, delivered as soon as possible

1 Introduction

Direct Memory Access (Direct Memory Access), referred to as DMA. DMA is a component of the CPU used to "transfer" (copy) data from one address space to another address space. The data copy process does not require CPU intervention, and the CPU is notified when the data copy ends.

Therefore, when a large amount of data is copied, using DMA can free up CPU resources. The DMA data copy process is typically as follows:

  • memory -> memory, copy between memory

  • Peripherals -> memory, such as uart, spi, i2c and other bus receiving data process

  • Memory -> peripherals, such as uart, spi, i2c and other bus data transmission process

2 Is it necessary to use DMA for serial ports?

Serial port (uart) is a low-speed serial asynchronous communication, suitable for low-speed communication scenarios, and the baud rate usually used is less than or equal to 115200bps.

For communication scenarios with a baud rate less than or equal to 115200bps and a small amount of data, it is generally unnecessary to use DMA, or the use of DMA does not give full play to the role of DMA.

For large numbers, or when the baud rate is increased, DMA must be used to release CPU resources, because high baud rates may bring such problems:

  • For sending, use cyclic sending, which may block threads, consume a lot of CPU resources to "carry" data, and waste CPU

  • For sending, using interrupt sending will not block the thread, but it needs to waste a lot of interrupt resources, and the CPU frequently responds to the interrupt; with a baud rate of 115200bps, 11520 bytes are transmitted in 1s, and it takes about 69us to respond to an interrupt. If the baud rate is further increased, Will consume more CPU resources

  • For receiving, if the traditional interrupt mode is still used for receiving, it will also consume a lot of CPU resources due to frequent interrupts.

Therefore, in high baud rate scenarios, it is very necessary for the serial port to use DMA.

3 Implementation methods

f167e54f63e8f34549109acc3dbca9df.png
overall design

4 STM32 serial port uses DMA

Regarding the use of DMA on the STM32 serial port, there are many development board routines and tutorials by some bloggers on the Internet. The usage steps, processes, and configurations are basically the same, and there is nothing wrong with the correctness, but they are all basic demo examples, which are no problem as a learning process; the actual use of the project lacks rigor, and when the amount of data is large, it may lead to abnormal data.

testing platform:

  • STM32F030C8T6

  • UART1 / UART2

  • DMA1 Channel2—Channel5

  • ST standard library

  • Main frequency 48MHz (external 12MHz crystal)

2775dc8f55b55ed8ab8b3a058c699b91.png
insert image description here

5 Serial port DMA reception

5.1 Basic Process

6a17d9d97ecd30b7ff00f791283f75d3.png
Serial port receiving flow chart

5.2 Related configuration

key step

【1】Initialize the serial port

[2] Enable serial port DMA receive mode, enable serial port idle interrupt

[3] Configure the DMA parameters, enable the DMA channel buf half-full (transfer half of the data) interrupt, buf overflow (transfer data complete) interrupt

Why do you need to use the DMA channel buf half-full interrupt?

Many tutorials and examples of serial port DMA mode reception basically use "space interrupt" + "DMA transfer completion interrupt" to receive data.

In essence, this is risky. When the DMA transfer data is completed, the CPU intervenes to start copying the DMA channel buf data. If the serial port continues to have data coming in at this time, the DMA continues to transfer the data to the buf, and the data may be overwritten, because the DMA data is transferred. is not controlled by the CPU, even if you turn off CPU interrupts.

The rigorous approach needs to do double buf, and the CPU and DMA each access a piece of memory alternately, that is, " ping- pong cache ". The processing flow steps should be as follows:

[1] The first step, DMA first transfers the data to buf1, and informs the CPU to copy the buf1 data after the transfer is completed.

[2] In the second step, the DMA transfers the data to buf2, which will not conflict with the CPU copying the buf1 data

[3] In the third step, the buf2 data transfer is completed, and the CPU is notified to copy the buf2 data

[4] After the third step is executed, the DMA returns to the first step and keeps looping

10e470ab54f09cf535e02070e0e6f25b.png
Double buffer DMA data transfer process

The STM32F0 series DMA does not support the double buffer (subject to the specific model) mechanism, but provides a buf "半满中断".

That is, when the data is transferred to half the size of buf, an interrupt signal can be generated. Based on this mechanism, we can implement the double-buffering function, just open up the buf space a bit larger.

[1] In the first step, when the DMA transfers the data to the first half of the buf, a "half full interrupt" is generated, and the CPU copies the first half of the buf data

[2] In the second step, DMA continues to transfer data to the second half of buf, which will not conflict with the CPU copying the first half of buf data

[3] In the third step, the data in the second half of buf is completed, triggering the "overflow interrupt", and the CPU copies the data in the second half of buf

[4] After the third step is executed, the DMA returns to the first step and keeps looping

9880a85ee305da43a81984cc60ffff41.png
Use half-full to interrupt the DMA data transfer process

The UART2 DMA mode receiving configuration code is as follows, which is basically the same as the configuration of other peripherals using DMA, pay attention to the key configuration:

  • Serial port receiving, DMA channel working mode is set to continuous mode

  • Enable DMA channel to receive buf half-full interrupt, overflow (transfer complete) interrupt

  • Clear the relevant status flags before starting the DMA channel to prevent chaotic data transmission for the first time

b1381c2d9fd4450c75be8535c7bf388d.png

The DMA error interrupt “DMA_IT_TE”is generally used for early debugging to check the number of DMA errors. The release software may not enable this interrupt.

5.3 Receive processing

Based on the above description mechanism, the serial port data is received by DMA, and there are three interrupt scenarios that require the CPU to copy the buf data to the fifo, namely:

  • DMA channel buf overflow (transfer complete) scenario

  • DMA channel buf half full scene

  • Serial port idle interrupt scenario

The first two scenarios have been described in the previous article. The serial port idle interrupt means that after the data transmission is completed, the serial port monitors that there is no data coming in for a period of time, and then triggers the generated interrupt signal.

5.3.1 Receive data size

The data transmission process is random, and the data size is also indeterminate. There are several types of situations:

  • The data is just an integer multiple of the DMA receiving buf, which is the ideal state

  • If the amount of data is less than the DMA receiving buf or less than half of the receiving buf, the serial port idle interrupt will be triggered.

Therefore, we need “DMA通道buf大小”、“DMA通道buf剩余空间大小”、“上一次接收的总数据大小”to calculate the current received data size based on it.

/* 获取DMA通道接收buf剩余空间大小 */
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);

DMA channel buf overflow scenario calculation

接收数据大小 = DMA通道buf大小 - 上一次接收的总数据大小

DMA channel buf overflow interrupt handler:

bd4c50c0b80123482db1eface3c00449.png

Calculation of DMA channel buf half-full scenario

接收数据大小 = DMA通道接收总数据大小 - 上一次接收的总数据大小
DMA通道接收总数据大小 = DMA通道buf大小 - DMA通道buf剩余空间大小

DMA channel buf half-full interrupt handler:

60f6141626f4d36cf5101ecd887dc4c1.png

Serial port idle interrupt scenario calculation

The calculation method of the received data in the serial port idle interrupt scenario is the same as that in the "DMA channel buf half-full scenario".

Serial port idle interrupt handler

Note: The serial port idle interrupt processing function, in addition to copying the data to the serial port receiving fifo, can also add special processing, such as the serial port data transmission completion flag, indefinite length data processing, and so on.

5.3.2 Receive data offset address

To copy the valid data into the fifo, in addition to knowing the size of the valid data, it is also necessary to know the offset address where the data is stored in the DMA receiving buf.

The effective data offset address only needs to record the total size of the last received, that is, the value is cleared by the DMA channel buf full interrupt handler, because the next data will be stored from the beginning of the buf.

Clear the data offset address in the DMA channel buf overflow interrupt handler:

4e7cb5ff820f1919a406895a2631b317.png

5.4 Application to read serial port data method

After the previous processing steps, the serial port data has been copied to the receiving fifo, and the application task only needs to obtain the data from the fifo for processing. The premise is that the processing efficiency must be greater than the efficiency of the DAM receiving and transporting data, otherwise the data will be lost or overwritten.

6 Serial port DMA sending

6.1 Basic Process

6a51b1e36c591611f023db252bce8157.png
Serial port sending flow chart

6.2 Related configuration

key step

【1】Initialize the serial port

【2】Enable serial port DMA transmission mode

[3] Configure the DMA transmission channel. This step does not require initial settings. Only configure the DMA transmission channel when there is data to be transmitted.

The UART2 DMA mode transmission configuration code is as follows, which is basically the same as the configuration of other peripherals using DMA, pay attention to the key configuration:

  • Serial transmission is yes, the DMA channel working mode is set to single-shot mode (normal mode), and the DMA is reconfigured every time data needs to be sent

  • Enable the DMA channel transfer completion interrupt, and use the interrupt information to process some necessary tasks, such as clearing the sending state and starting the next transfer

  • Clear the relevant status flags before starting the DMA channel to prevent chaotic data transmission for the first time

6.3 Send Processing

The serial port data to be sent is stored in the sending fifo. The task that the sending processing function needs to do is to cyclically query whether there is data in the sending fifo. If there is, copy the data to the DMA sending buf, and then start the DMA transmission.

The premise is that you need to wait for the completion of the last DMA transfer, that is, the DMA receives the DMA transfer completion interrupt signal "DMA_IT_TC".

Serial port send processing function:

d8df0c6dce0206b1d1b321b729179f8b.png

  • Pay attention to the sending status flag, which must be set to "sending status" first, and then start the DMA transfer. If the steps are reversed, when the amount of data to be transferred is small, the DMA transfer time is short, and the “DMA_IT_TC”interrupt may be executed before the "send status flag is set", resulting in the program misjudging that the DMA has been processing the sending state (the sending flag cannot be cleared).

Note: Regarding the DMA sending data start function, some blog articles describe that you only need to change the size of the DMA sending buf; after testing, it is found that this method is feasible when the amount of data sent is small. Trigger DMA send completion interrupt. Therefore, the reliable way is to reconfigure all parameters of the DMA channel every time DMA transmission is started. This step is just a configuration register process, which does not take up much CPU execution time in essence.

DMA transfer completion interrupt handler:

fa0f195a334e056d09b8bd5dcccb5683.png

The above serial port sending processing function can be called in several situations:

  • Main thread task call, provided that the thread cannot be blocked by other tasks, otherwise it will cause fifo overflow

    44e91a3f675757deea1786315562e641.png

  • Called by timer interrupt

    bf3d649ddf209b600473fc3e53c11018.png

  • Called in DMA channel transfer completion interrupt

    8bc59e4854c2663b82fef440e8ecb57c.png

How much data is copied to DMA to send buf each time:

Regarding this issue, it is related to the specific application scenario. The principle to follow is: as long as the amount of data sent to the fifo is greater than or equal to the size of the DMA send buf, the DMA send buf should be filled, and then the DMA transfer is started, so as to give full play to the DMA performance.

Therefore, it is necessary to take into account the efficiency of each DMA transmission and the real-time performance of serial data flow, and refer to several types of implementations:

  • Periodically query and send fifo data, start DMA transmission, and make full use of DMA transmission efficiency, but may reduce the real-time performance of serial data flow

  • Real-time query to send fifo data, plus timeout processing, the ideal method

  • Processed in DMA transfer completion interrupt to ensure real-time continuous data flow

7 Serial device

7.1 Data Structures

7.2 External interface

8 Complete source code

Code repository:

https://github.com/Prry/stm32f0-uart-dma

pressure test:

  • 1.5Mbps baud rate, serial assistant sends 1k bytes of data per millisecond, stm32f0 DMA receives data, and then sends back to serial assistant through DMA, no pressure.

  • 1.5Mbps baud rate, can transmit large file test, save the received data as a file, and compare it with the source file.

  • The serial port high baud rate test requires the support of both the USB to TLL tool and the serial port assistant. We recommend the USB to TTL tool of CP2102 and FT232 chips.

feed1dd5b2686a872e6c0fc4f2042bb7.png
1.5Mbps serial port loopback stress test
原文地址:blog.csdn.net/qq_20553613/article/details/108367512

Transferred from the public number: Embedded Intelligence Bureau

Copyright statement: This article comes from the Internet, and the copyright belongs to the original author. Copyright issues, please contact to delete.

—— The End ——

Recommended in the past

Quantum charging, filling a car in 9 seconds! Is this mysticism?

GD32 replaces STM32, what are the differences? Don't step on these pits...

Efficient analysis of single-chip communication protocol, the most practical method

The most suitable communication protocol for single-chip microcomputer, how to design?

46 million units sold! The Road to Raspberry Pi

Good tool, don't hide it! Introduce a tool to improve efficiency

Click the card below to follow me

Guess you like

Origin blog.csdn.net/u010632165/article/details/123836318