Forum : ST7/STM8
Post Information | Post |
---|---|
August 28, 2009 - 5:42pm
|
In the code below, the second part of the if (TTS > STS) statement produces no code. Removing 'volatile' from the definition of TTS resolves the issue. Am I missing something obvious here? I think I can remove volatile from the definition in my code, as it was there only to ensure that the timer register would be read in the correct order (high byte first) when using optimization. -- ***** BEGIN CODE ***** #include void Func1(void); unsigned short STS; void main(void) for (i=0; i<100; i++) Func1(); while(1); void Func1(void) volatile unsigned short TTS = T16ACR; if (TTS > STS) if (Duration > MAX_D) MAX_D=Duration; } |
That is similar to the problem I posted here: http://raisonance-forum.xsalto.com/viewtopic.php?id=2945
Do you have the automatic variable relocation enabled? My problem also concerned comparing volatiles.
Hi Blasio,
We spent a bit of time trying to understand what happens in your code. The compiler is *right* when simplifying your code:
In the line:
Duration = ((TTS-STS) + 65536);
The 65536 is useless, as i + 65536 will always give back i as a result. Hence the compiler has been simplifying your code up to the point where the test vanishes.A question can be "why does the non-volatile version of the code provide a fully functional code?". The answer here is that when simplifying the code, the optimizer is performing some factorization of assembly code statements. But at a given point it needs to factorize two "POP A", which is dangerous and is hence not performed. This is why the test remains in the non-volatile version; but if you look at the assembly code produce you will see that the statements are the same whatever the result of the comparison.
As a baseline, instead of:
You can just write:
Duration = TTS-STS;
The C will guarantee that the computation is correct.
I hope this helps,
Bruno
Yes, I forgot that with unsigned variables the result is valid even if an overflow occurs. Thanks for the response.
--
Blasio