cancel
Showing results for 
Search instead for 
Did you mean: 

Fastest way of data sending to multiple uarts

ismail fatih iltar
Associate II
Posted on June 27, 2018 at 09:30

Hi everyone, im trying to send datas to 8 uarts+usarts on stm32f7 mcu. I'm getting datas from ethernet wtih netconn connection. I'm using FreeRTOS and lwIP stack. I have a task that calls netconn_recv(conn, &buf); in infinite loop. When netcon_recv function returns OK i parse datas. Than i send datas to proper ports by interrupt method. But when more than 1 uart data appear at ethernet, my FPS of uart output starts to decrease. I need an advice to increase the speed of data send system.


void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart6)
{
usart6_tx_ready_u8 = TRUE;
}
if(huart == &huart1)
{
usart1_tx_ready_u8 = TRUE;
}
if(huart == &huart2)
{
usart2_tx_ready_u8 = TRUE;
}
if(huart == &huart3)
{
usart3_tx_ready_u8 = TRUE;
}
if(huart == &huart8)
{
usart8_tx_ready_u8 = TRUE;
}
if(huart == &huart7)
{
usart7_tx_ready_u8 = TRUE;
}
if(huart == &huart5)
{
usart5_tx_ready_u8 = TRUE;
}
if(huart == &huart4)
{
usart4_tx_ready_u8 = TRUE;
}
}
/* SEND 4 UART */
void data_send(uint8_t port_no, uint8_t* data_buffer, test_t* TEST, uint16_t size)
{
switch (port_no)
{
case (uint8_t)PORT1:
{
usart5_tx_ready_u8 = FALSE;
MX_UART5_Init2();//change baudrate to SET1
HAL_UART_Transmit_IT(&huart5,TEST->start_buffer,1);
while(usart5_tx_ready_u8 == FALSE);//wait callback
usart5_tx_ready_u8 = FALSE;
MX_UART5_Init();//change baudrate to SET2 again
HAL_UART_Transmit_IT(&huart5, data_buffer,size+1);
while(usart5_tx_ready_u8 == FALSE);
break;
}
case (uint8_t)PORT2:
{
usart6_tx_ready_u8 = FALSE;
MX_USART6_UART_Init2();//change baudrate to SET1
HAL_UART_Transmit_IT(&huart6,TEST->start_buffer,1);
while(usart6_tx_ready_u8 == FALSE);//wait callback
usart6_tx_ready_u8 = FALSE;
MX_USART6_UART_Init();//change baudrate to SET2 again
HAL_UART_Transmit_IT(&huart6, data_buffer,size+1);
while(usart6_tx_ready_u8 == FALSE);
break;
}
case (uint8_t)PORT3:
{
usart7_tx_ready_u8 = FALSE;
MX_UART7_Init2();//change baudrate to SET1
HAL_UART_Transmit_IT(&huart7,TEST->start_buffer,1);
while(usart7_tx_ready_u8 == FALSE);//wait callback
usart7_tx_ready_u8 = FALSE;
MX_UART7_Init();//change baudrate to SET2 again
HAL_UART_Transmit_IT(&huart7, data_buffer,size+1);
while(usart7_tx_ready_u8 == FALSE);
break;
}
case (uint8_t)PORT4:
{
usart8_tx_ready_u8 = FALSE;
MX_UART8_Init2();//change baudrate to SET1
HAL_UART_Transmit_IT(&huart8,TEST->start_buffer,1);
while(usart8_tx_ready_u8 == FALSE);//wait callback
usart8_tx_ready_u8 = FALSE;
MX_UART8_Init();//change baudrate to SET2 again
HAL_UART_Transmit_IT(&huart8, data_buffer,size+1);
while(usart8_tx_ready_u8 == FALSE);
break;
}
default:
{
break;
}
}
}
/* SEND OTHER 4 UART */
void data_send2(uint8_t port_no, uint8_t* data_buffer, test_t* TEST, uint16_t size)
{
...
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

#usart #stm32f-uart #uart-interrupt #ethernet-stm32f7
14 REPLIES 14
Posted on June 27, 2018 at 11:16

You need to reimplement the data_send so it doesn't serialize/block doing one channel after another. You need to send the multiple streams in parallel.

You could perhaps use a state table for each port, looping until all have completed the sequencing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
henry.dick
Senior II
Posted on June 27, 2018 at 12:21

1) use uart interrupts to send data; all you need to do is to register the starting address of the text. 

2) don't repeatedly reset the uart - no point in doing that unless you are dynamically changing the baud rate / uart configuration.

3) try to use vectored interrupts.

Posted on June 27, 2018 at 11:40

How can i send in parallel ?

Posted on June 27, 2018 at 12:48

dhenry wrote:

1) use uart interrupts to send data; all you need to do is to register the starting address of the text. 

2) don't repeatedly reset the uart - no point in doing that unless you are dynamically changing the baud rate / uart configuration.

3) try to use vectored interrupts.

Hi dhenry,

1) im already using HAL_UART_Transmit_IT function to use interrputs

2) i have to change baudrate while sending data :\

3) im generating codes from cubeMX and i use NVIC 

Posted on June 27, 2018 at 12:55

1. Then you loop around waiting for it to finish making it polling.

2. Then you chose to make it slow.

3. Then you chose to make it slow and complex.

Sounds like a case where the outcome contradicts the design framework.

Posted on June 27, 2018 at 14:37

1)if ı dont use flags at callback function how can i be sure the datas are sended and yes now i can call the  Inıt2() function to change baudrate ?

2)i need ~100us low pulse at uart. so i send zero at SET1 baudrate than i change it to SET2 normal comm. baudrate. 

3)what is the relationship betweeen codes that are generated by cubemx and NVIC speed :S

Posted on June 27, 2018 at 17:28

You use this serialized/sequenced mindset

               usart5_tx_ready_u8 = FALSE;

               MX_UART5_Init2();     //change baudrate to SET1                                                  

               HAL_UART_Transmit_IT(&huart5,data_buffer,size+1);

               while(usart5_tx_ready_u8 == FALSE);     //wait callback

               usart6_tx_ready_u8 = FALSE;

               MX_USART6_UART_Init();     //change baudrate to SET1

               HAL_UART_Transmit_IT(&huart6, data_buffer,size+1);

               while(usart6_tx_ready_u8 == FALSE);     //wait callback

               usart7_tx_ready_u8 = FALSE;

               MX_UART7_Init2();          //change baudrate to SET1

               HAL_UART_Transmit_IT(&huart7,data_buffer,size+1);

               while(usart7_tx_ready_u8 == FALSE);     //wait callback

               usart8_tx_ready_u8 = FALSE;

               MX_UART8_Init2();          //change baudrate to SET1

               HAL_UART_Transmit_IT(&huart8,TEST->start_buffer,1);

               while(usart8_tx_ready_u8 == FALSE);     //wait callback

You want to use this kind of mindset

               usart5_tx_ready_u8 = FALSE;

               MX_UART5_Init2();     //change baudrate to SET1                                                  

               HAL_UART_Transmit_IT(&huart5,data_buffer,size+1);

               usart6_tx_ready_u8 = FALSE;

               MX_USART6_UART_Init();     //change baudrate to SET1

               HAL_UART_Transmit_IT(&huart6, data_buffer,size+1);

               usart7_tx_ready_u8 = FALSE;

               MX_UART7_Init2();          //change baudrate to SET1

               HAL_UART_Transmit_IT(&huart7,TEST->start_buffer,1);

               usart8_tx_ready_u8 = FALSE;

               MX_UART8_Init2();          //change baudrate to SET1

               HAL_UART_Transmit_IT(&huart8,data_buffer,size+1);

               while(usart5_tx_ready_u8 == FALSE);     //wait callback

               while(usart6_tx_ready_u8 == FALSE);     //wait callback

               while(usart7_tx_ready_u8 == FALSE);     //wait callback

               while(usart8_tx_ready_u8 == FALSE);     //wait callback

I'd use a stateful implementation, and use arrays so I don't have to write the same code 8 times.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 27, 2018 at 17:34

You're working in this serialized mindset where you wait for everything to complete, and you loop for each channel. Slowest possible outcome..

Use arrays so you don't have to replicate the same code multiple times

Use a state machine method where you call repeatedly, but check the stage each transfer is on, and leave, don't wait.

This way you get 8 transfers occurring concurrently. As each of the first transfers completes, start the next. You finish when all channel are complete/idle.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 27, 2018 at 19:57

Forgive me for my fool but i cant understand. I structed swich case so i dont send all port for each time. If ethernet sends just port no:1 data i call data_send function one time with port_no=1 and it enteres just first case and exit. If ethernet sends 1,2,4 ports datas i call three times data_send function with  portno=1,portno=2,portno=4 seperately.