cancel
Showing results for 
Search instead for 
Did you mean: 

UART Printing does not work when Interrupts are enabled and Link Time Optimization is on

Dominik Lorych
Associate III

Hi,

I have some strange problem with UART printing. It does not work when Interrupts are enabled and Link Time Optimization is used. Or rather the UART prints the first character and then seems to get stuck. If I either disable interrupts in the code (__disable_irq()) or disable the LTO, then it works fine. I tested this with two different devices (Nucleo-G071RB and Nucleo-L476RG). Any idea why this combination does not work?

3 REPLIES 3

LTO is an aggressive optimization step, which brings up bugs otherwise covered usually by the invisibility of eliminable code/variables across modules.

It's the same as with other optimizations, the most usual culprit is incorrect (missing) use of volatile, especially if interrupts are involved; but other causes are not excluded of course.

Debug as usually. If you used any "library", that's your code and your problem now, too.

JW

berendi
Principal

With -flto enabled, the compiler can optimize code across multiple files, it may be able to keep more variables in registers, so some code might not pick up changes to some variables which are modified in an interrupt handler, and not declared as volatile.

Without -flto, every function call to another source file acts as a memory barrier, the compiler must save all global values back to memory, and reload them afterwards, because it has no way to know whether the called function changes them as a side effect.

The -flto option is deliberately hidden in STM32CubeMX, because HAL functions use volatile at the wrong places, as if the developers who have never understood its purpose had to fill some quota. Frequent calls to functions in another source file significantly increases the chance that this mess works, as long as these calls are all implicit memory barriers.

Thanks. Didn't know about the "memory barrier"-effect.