Skip to main content
Explorer II
August 21, 2024
Solved

Computation error occurs sporadically

  • August 21, 2024
  • 2 replies
  • 1024 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

    This topic has been closed for replies.
    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

    KnarfBAnswer
    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

    TBergAuthor
    Explorer 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

     

    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.