Firing multiple printfs with UART DMA Tx -> crap -> printf memory alloc?
Okay, thread number 371982 about the STM's UART... - but maybe not?
I recently found that I'm using some blocking printf / UART version, so I wanted to change that to non-blocking via DMA.
So far so good, works flawlessly.
Until I start "firing" the printfs, then it looks like parts of the previous strings are overwritten by the following printfs.
I think that I wait for all the right flags before starting a new DMA TX (I know that if the DMA says it's finished that there might still by a byte in the peripheral) in _write(), and the single printf (or more with some pauses) shows me that it's generally working.
So this works:
printf("string1");
... do other stuff...
printf("string2");
This doesn't:
printf("string1");
printf("string2");
So after having checked UART and DMA again, could it be GCC's printf memory handling? So that rapid printfs use the same memory space, and older data is overwritten by newer printfs?
Here's my _write() function:
Note: if I put the DMA transmit before the while loop, everything works fine, but then I'm back in blocking mode for a single printf.
int _write(int file, char *data, int len)
{
HAL_StatusTypeDef HalRet = HAL_OK;
uint32_t TickUartStart = HAL_GetTick();
/* wait for uart ready with timeout */
while( 1 )
{
if( (HAL_GetTick() - TickUartStart) > UART_TX_DMA_TIMEOUT_MS )
{
u8Uart3TxTimeout++;
return 0;
}
if( (u8Uart3TxActive == 0) &&
(USART3->ISR & (USART_ISR_TC | USART_ISR_TXE)) &&
(huart3.gState == HAL_UART_STATE_READY) )
{
break;
}
}
u8Uart3TxActive = 1; // reset in DMA complete callback
HalRet = HAL_UART_Transmit_DMA(&huart3, (uint8_t *)data, len);
/* return # of bytes written */
if( HalRet != HAL_OK ) return 0;
return len;
}