2017-10-02 05:59 AM
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 #asynchronous2017-10-02 06:57 AM
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.
2017-10-02 09:21 AM
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.
2017-10-02 09:45 AM
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;
}
2017-10-09 03:48 AM
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.
2017-10-09 11:25 AM
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.