cancel
Showing results for 
Search instead for 
Did you mean: 

Questions about UART_TwoBoards_ComIT example in STM32 Examples

Dimitris Paraskevopoulos
Associate III
Posted on October 02, 2017 at 14:59

I will focus my question on the receiver board to make it simpler.

In the example we are resetting a global flag and then requesting to receive some bytes. Then we wait until the HAL_UART_RxCpltCallback sets the flag while potentially doing some work instead of just waiting for the data as is done in the polling example (synchronous). When we receive the data we echo back the received data.

First of all I want to verify that the example as it currently is is essentially a synchronous operation if we do not add any code to the  while (UartReady != SET) loop.

I would like to know if this asynchronous + polling to see if the global variable has been set is the best way (Least amount of time spent not doing any meaningful work) to do this asynchronous communication.

Isn't this polling wasting CPU resources? Is there a different way to do this?

If I wanted to have a simple system where receiver receives some data processes them and returns back then should the pseudocode be:

while(1){

   HAL_UART_Receive_IT

   while (UartReady != SET) {

      process_data

   }

   UartReady = RESET;

   HAL_UART_Transmit_IT

   while (UartReady != SET){

      process_data

   }

}

So basically whenever we are not doing work on receiving or transmitting we are processing the data.

Is there a design pattern for this? If so how is it called.

Should we queue the next transmission whenever we receive some data i.e. in HAL_UART_RxCpltCallback along with setting the UartReady flag?

#stm32 #uart-it #asynchronous
5 REPLIES 5
Posted on October 02, 2017 at 15:57

I would generally look to doing receive and transmit in parallel as you really can't control when data will be received, and if not handled in a timely fashion will result in overruns and data loss.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 02, 2017 at 16:21

Not entirely sure what you mean by doing it in parallel.

Do you suggest using SPI instead? Could you give an example or even better give pseudocode?

Cheers Clive.

Posted on October 02, 2017 at 16:45

Parallel, ie concurrently, not blocking Wait for A, Wait for B

while(1)

{

  if (RxIdle) HAL_UART_Receive_IT;

  if (TxIdle) HAL_UART_Transmit_IT;

 if (RxReady) ProcessRx;

 if (TxReady) ProcessTx;

 ProcessPump;

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 09, 2017 at 10:48

So I had some time over the weekend to try and implement this but I couldn't. It wasn't clear to me what are the conditions used for RxIdle and TxIdle. I assumed that RxReady refers to UartHandle.rxState == HAL_UART_STATE_READY

and TxReady refers to UartHandle.gState == HAL_UART_STATE_READY. Which essentially means either that Uart has just been initialized or that we have completed a reception or a transmission respectively. Even though I saw that there is a flag for RxIdle there wasn't one for TxIdle.

Can you please tell me if my assumption is correct and what are the conditions for RxIdle and TxIdle?

Thank you very much.

Posted on October 09, 2017 at 18:25

This was more of a tracking flag from your side as to whether you currently have any data in-flight or not. ie RxIdle is cleared when you use HAL_USART_Receive_IT(), and set when the call-back closes out the transaction. Things like RxReady reflects if the call-back buffered any data.

You could, I suppose, rely on the state/error from HAL, but it would be more effective to have your own state machine, so you don't call functions when you know you already have an active request pending.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..