AnsweredAssumed Answered

printf with HAL_UART_Transmit_IT?

Question asked by Toby on Nov 9, 2016
Latest reply on Mar 31, 2017 by Toby
I am new to the hal libraries (but not stm32 devices) and struggle to see how HAL_UART_Transmit_IT is expected to be used for something simple like printf over uart.

Take a blocking example:
void PRINT_MESG_UART(const char * format, ... )
{
  va_list ap;
  uint8_t buffer [128];
  int n;
   
  va_start(ap, format);
  n = vsnprintf ((char*)buffer, 128, format, ap);
  va_end(ap);
   
  //notify_uart(buffer, n);
  if(HAL_UART_Transmit(&UartHandle, (uint8_t*)buffer, n, 300) != HAL_OK) {
    Error_Handler();
  }
}
That works fine.
But what if I want it non blocking under interrupts?
What I have come up with is as follows:
uint8_t buffer [128];
void PRINT_MESG_UART(const char * format, ... )
{
   va_list ap;
   int n;
 
   while (UartHandle.gState != HAL_UART_STATE_READY)
      ; // will overwrite the buffer otherwise, (needs a timeout and error handling)
 
   va_start(ap, format);
   n = vsnprintf ((char*)buffer, 128, format, ap);
   va_end(ap);
 
  HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)buffer, n) == HAL_BUSY) ;
}
This works, but is pretty poor as it still blocks if the buffer is already in use.

Is there a better way? The obvious way is to use the traditional method of a circular buffer. eg
bool u_put_byte(uint8_t data)
{
   bool ok = FALSE;
   if ((uart_buffer.txin + 1) % S_BUF_SIZE != uart_buffer.txout)
   {
      uart_buffer.txbuf[uart_buffer.txin] = data;
      uart_buffer.txin = (uart_buffer.txin + 1) % S_BUF_SIZE;
      ok = TRUE;
   }
   SET_BIT(UartHandle.Instance->CR1, USART_CR1_TXEIE);
 
   return ok;
}
void PRINT_MESG_UART(const char * format, ... )
{
  va_list ap;
  uint8_t buffer[S_BUF_SIZE];
  int n;
 
  va_start(ap, format);
  n = vsnprintf ((char*)buffer, S_BUF_SIZE, format, ap);
  va_end(ap);
 
  int i = 0;
  while ((buffer[i] != 0) && (i < S_BUF_SIZE) && (i < n))
  {
     while (!u_put_byte(buffer[i])) // keep attempting until it succeeds
        ;                                          // timeout and error handling here.
     i++;
  }
}
However the HAL uart library functions do not appear to support this sort of buffer. Am I correct?

Outcomes