cancel
Showing results for 
Search instead for 
Did you mean: 

UART DMA race condition bug

Taehyun9203
Associate

Hi, I want to discuss this problem in UART DMA on STM32F4 boards

I am sorry to upload picture rather than code.

Moreover, my English is not proficient and please understand.

I tested my code under nucleo-f429zi.

-------------------------------------------

First of all, I configured UART3 with DMA option on board.

The below figure is the code I tested

Taehyun9203_0-1693113902193.png

I thought that if I called UART_Receive_DMA function in the code, the data only receive DMA method.

The reason is that UART_Start_Receive_DMA() called by HAL_UART_Receive_DMA() make receiver state (RxState) HAL_UART_STATE_BUSY_RX in line 3259 of second picture.

Taehyun9203_4-1693114628194.png

So when I called HAL_UART_Recevie() which does not use DMA method, HAL_UART_Recevie() cannot receive any data if HAL_UART_Receive_DMA() is already called before HAL_UART_Recevie().

This is because HAL_UART_Recevie() can receive data when receiver state is free (RxState == HAL_UART_STATE_READY) (below figure 1271 line) 

Taehyun9203_5-1693114892969.png

So I thought that if user makes the RxState HAL_UART_STATE_READY after calling HAL_UART_Receive_DMA(), HAL_UART_Receive() could work (below figure)

Taehyun9203_6-1693115098198.png

I tested this code and result is weird.

When I give input string "Hello world!!" via serial communication to UART, UART cannot receive first character of the input string.

Taehyun9203_7-1693115151259.png

I think that the problem is HAL_UART_Receive_DMA() and HAL_UART_Receive() only check once receiver state (RxState) and both functions are ready to receive data.

So this code may make race condition between both functions.

I want to hear your opinion about this.

 

 

 

 

 

 

 

3 REPLIES 3
Johi
Senior III

Mixing DMA and not DMA is not such a good idea.

Below a simple demo that sends data and reads data from another device such as a PC.

 

TDK
Guru

You can't have HAL_UART_Receive() and HAL_UART_Receive_DMA() working simultaneously. The peripheral has a single receive lane, and both of these functions use it. As you saw, the functions will return HAL_BUSY if one of them is already working.

> So I thought that if user makes the RxState HAL_UART_STATE_READY after calling HAL_UART_Receive_DMA(), HAL_UART_Receive() could work (below figure)

This is nonsense. Forcing the state to reflect something else, just so a function returns HAL_OK, doesn't get around the underlying limitation of a single receive lane.

If you feel a post has answered your question, please click "Accept as Solution".
Mahmoud Ben Romdhane
ST Employee

Hello @Taehyun92039203.

Thank you for posting and welcome to the ST Community.

I advise you to take a look at this ST Lab: STM32CubeMX basics: 10.11 STM32Cube HAL labs UART - UART DMA - YouTube.

The video explains how to use the UART with DMA using STM32F4 boards.

You can also consult this wiki: Getting started with UART - stm32mcu

Thank you.

Mahmoud.