cancel
Showing results for 
Search instead for 
Did you mean: 

UART DMA with RTOS

Adam90
Associate II

Hi all,
I spent hours but I cannot make UART work in DMA circular mode with RTOS (CMSIS V2).
Can someone send me a simple example ?
I would like to receive characters from PC (various length commands: 8-10 chars) and process them in another task parallel. Then save the position and next time start processing the commands in the buffer from the previous position.

What I experienced is that ReceiveBuffer contains one only character. When I put a breakpoint at HAL_UART_Receive_DMA line and send the characters, in next iteration I see the whole string received.
I guess somehow I have to wait till the streaming is finished.

Finally a made it work. Hw issue is always the last thing what I'm suspecting...
I haven't noticed this in device manager:

Adam90_0-1727526459199.png

Replacing the USB-UART converter solved the issue and uC receiving the incoming stream with DMA.

 

This snippet seems working:

 

 

void StartDefaultTask(void *argument)

{

HAL_UARTEx_ReceiveToIdle_DMA(&huart5, (uint8_t*)ReceiveBuffer, 256);

for(;;)

{

if(ReceiveBuffer[shift]!='\0')

{

osMessageQueuePut(MessageBufferQueueHandle, &(ReceiveBuffer[shift]), 0, 0); //saving to queue

ReceiveBuffer[shift]='\0';

shift++;

}

osDelay(50);

}

}

 

 

 

 

 

5 REPLIES 5
Imen.D
ST Employee

Hello @Adam90 and welcome to the Community :)

Please take a look at this GitHub link.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Karl Yamashita
Lead III

We have no idea what you're doing. Show your interrupt code

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

Thanks for the feedback. I've already seen this repo. 
My problem with this:
- it is using LL functions
- and it is saving the incoming stream to QUEUE instead of DMA

Pavel A.
Evangelist III

I've already seen this repo

Great so this is basically how it should be done. The cyclic DMA receiver can be combined with another component by Mr. Majerle, the ring buffer. The buffer used for DMA receive coincides with the software ring buffer so no copying is needed. The DMA interrupt handlers or callbacks only synchronize the pointers and signal the reader task that new data arrived. Waking the task is fast and does not involve moving any data or queues. Sorry I don't have a ready code to share but that's the idea.

 

 

 

Karl Yamashita
Lead III

Don't edit your original post showing the fix. Some of us have already seen your post and are following along. In most cases, we are no longer looking at the 1st post, but the latter. I had no idea you found a fix because i wasn't notified by email.

To make it easier to follow along and not to see strike through your post, just reply with the fix, then mark it as the Accept as Solution

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.