cancel
Showing results for 
Search instead for 
Did you mean: 

printf and puts function not working in release build firmware

chai2145
Senior

Hi everyone,

I’m working on an STM32 firmware project (HAL + CubeIDE). I’m trying to output debug messages to Tera Term via UART using printf and puts.

Here’s the situation:

  • Debug build: Both printf and puts work perfectly.

  • Release build: Calling printf or puts causes the MCU to reset immediately. Maybe due to watchdog reset and these function call cause the MCU freezing.

I also retarget the printf function by implemented the following: 

int __io_putchar(int ch) {
    while (!(huart1.Instance->ISR & USART_ISR_TXE));
    huart1.Instance->TDR = (uint16_t)ch;
    return ch;
}

int _write(int file, char *ptr, int len) {
    for (int i = 0; i < len; i++) {
        __io_putchar(ptr[i]);
    }
    return len;
}

My questions:

  1. Why do printf and puts crash/reset in Release but work in Debug?

  2. Are there known issues with _write or __io_putchar in Release builds?

  3. Any recommended approach to safely use printf/puts in Release firmware for UART output?

Thanks in advance!

 

12 REPLIES 12

Hi, 

 

Sorry, I'm using STM32L071RZ, I think this series doesn't support semihosting.  

Sorry, what is hardware flow control. 

The UART initialization code is in below and it call before any printf and puts function.

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

 it 

> Sorry, I'm using STM32L071RZ, I think this series doesn't support semihosting.  

Semihosting is not a MCU feature.

> Sorry, what is hardware flow control. 

I highly suggest to take the time and read the USART/UART section of the reference manual of your MCU.
Especially in relation to asynchronous serial mode, event / interrupt handling, and register interface.


@chai2145 wrote:

Sorry, what is hardware flow control.  


That's where hardware signals are used by the connected devices to enable/disable the comms between them.

https://en.wikipedia.org/wiki/Flow_control_(data)#Hardware_flow_control 

 

You disable it here:

huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.