Skip to main content
TBerg
Associate II
August 21, 2024
Solved

Computation error occurs sporadically

  • August 21, 2024
  • 2 replies
  • 1025 views

Hi!

I am performing a calculation in an interrupt as this:

L1L2_filteredTimeNegFlank = ((TIM_GetCounter(TIM16)*50) + 206*L1L2_filteredTimeNegFlank)>>8;

But it seems like that it sporadically computes the wrong value and it disappears when I reformulate the calculation like this:
L1L2_filteredTimeNegFlank = TIM_GetCounter(TIM16)*50;
L1L2_filteredTimeNegFlank = L1L2_filteredTimeNegFlank + 206*L1L2_filteredTimeNegFlank;
L1L2_filteredTimeNegFlank = L1L2_filteredTimeNegFlank>>8;

Does anyone know why this happen?

Thanks

/Tomas

Best answer by KnarfB

few general ideas for finding the root cause:

- forgotten volatile declaration when using a global variable in an interrupt?

- cache issues (what core?)

- do you see a pattern in when & what wrong value(s) occur?

- timing glitches by other interfering interrupts like SysTick

- check / change interrupt priorities

- make your handler uninterruptable by using __disable_irq()

- change optimization level

- compare assembler code of both verions

hth

KnarfB

2 replies

KnarfB
KnarfBBest answer
Super User
August 21, 2024

few general ideas for finding the root cause:

- forgotten volatile declaration when using a global variable in an interrupt?

- cache issues (what core?)

- do you see a pattern in when & what wrong value(s) occur?

- timing glitches by other interfering interrupts like SysTick

- check / change interrupt priorities

- make your handler uninterruptable by using __disable_irq()

- change optimization level

- compare assembler code of both verions

hth

KnarfB

TBerg
TBergAuthor
Associate II
August 21, 2024

Hi KnarfB,

Thank you so much for your effort!

Seems like you are really experienced, as Im not :)

The mcu used is named STM32F030C8T6TR.

The variables are volatile.

How do I recognize if there is a cache issue?

Unfortunately I cannot see any pattern in the occurances.

The optimization level is set o none.

Interrupt priority is set to highest using nvic.

Interesting, when I disable/enable irqs as you suggest the problem occurs more often! This may be something!

Best regards,

Tomas

 

nouirakh
ST Employee
August 21, 2024

Hello @TBerg 

The issue you're encountering is likely due to the way the compiler optimizes and handles the complex expression in the first version of your code. When you break down the calculation into multiple steps, it becomes easier for the compiler to manage unexpected behavior.
Example of code with the steps broken down:
int tempCounter = TIM_GetCounter(TIM16) * 50;
int tempFilteredTime = 206 * L1L2_filteredTimeNegFlank;
int combinedResult = tempCounter + tempFilteredTime;
L1L2_filteredTimeNegFlank = combinedResult >> 8;

By breaking down the calculation into simpler steps, you make the code more readable and reduce the risk of compiler optimization issues or data type overflows. This approach also makes it easier to debug and verify each part of the calculation.