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!

 

4 REPLIES 4
Ozone
Principal II

Compare the build settings for debug and release.
Normally you have semihosting enabled for debug, which includes additional code and these outputs are routed via JTAG/SWD or an UART line.

Relase build setting do usually not.
This is why you have debug and release builds in the first place - you don't do debug printf()s in release versions.


I'm not using CubeIDE, so I don't know why it crashes.
With my toolchain, the  _write and __io_putchar calls are empty functions in the release version, and thus printf()s in the release build amount to nothing.

chai2145
Senior

The thing is my application support CLI function, accept commands from console like tera term and response accordingly.

Then don't use the semihosting interface for that, but a separate UART.

Or extend the release build settings accordingly.

Andrew Neil
Super User

You can still run the Release version in the debugger to see what's happening.

 


@chai2145 wrote:
  • Maybe due to watchdog reset and these function call cause the MCU freezing


Maybe instrument your code so that you can see if that actually is the case ...

 

As @Ozone said, check what's different between the builds - Optimisation level is another common one.

When increasing the optimisation level breaks your code, that usually indicates flaws in the code.

eg, failure to use 'volatile' where required...

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.