Question:
Code optimization double-edged sword,
An error occurs accidentally.
Static in GCC,
Difficult to detect after an error,
If you don't want to cover the road,
Volatile!
Laboratory development of the sensor network node using the AVR series microcontroller circuit board, AVR-GCC provides 5-level code optimization, because the node Running code is more complex, the functions such as routing, networking, data collection, data transmission, sleep, and time synchronization need to be completed. If optimization is not enabled, the Code has basically reached 160% of the single chip microcomputer capacity. The following is the code optimization configuration in the MAKEFILE file:
# Optimization level, can be [0, 1, 2, 3, S]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See Avr-libc FAQ .)
Opt = s
Among them, opt = s indicates that the S-level optimization is enabled. When this optimization is enabled, the compiled HEX file is immediately reduced from 160% of the single chip microcomputer capacity to nearly 40%.
Code optimization is great, and it is done by the compiler, but it has encountered a very big thing recently:
Static bool timer2_flag;
ISR (timer2_compa_vect)
{
Timer2_flag = true;
}
Int main (void)
{
...
Timer2_flag = false;
While (! Timer2_flag );
...
}
The timer2 settings and other Code are not listed here. After timer2 is interrupted, timer2_flag is set to a bit, and the code runs out of the while loop, but timer2 is not interrupted yet, after an afternoon call, I did not find the cause, because I have been wondering whether the interrupt settings are wrong or whether the timer2 timer pre-division, interrupt type, and so on are set incorrectly.
After an afternoon's problem, it was okay to add only one keyword to the code, that is, "volatile ".
Change the flag definition from static bool timer2_flag to static volatile bool timer2_flag;
As a result, the expected goal is achieved.
Why?
I clearly remember that static has nothing to do with its literal concept of static and unchanged. It is impossible for timer2_flag to become a constant because of this keyword, because the actual use of static should only limit the scope of use of this variable and cannot be used out of this file.
So why is this problem still occurring?
The answer lies in optimization. Although I want a flag that can be modified in the interrupt, the compiler does not think so, the compiler optimized all the code for modifying timer2_flag into one sentence. When the interrupt occurs, the timer2_flag value is not executed in the executable code as expected for each interruption;
The volatile keyword is a signal sent to the compiler: The timer2_flag variable is variable and often changed. Please do not optimize it. Therefore, this time the compiler let go of it, the program ran normally without optimizing the statement that modified it!
The compiler optimization code is really a double-edged sword. Moreover, the compiler is always less intelligent than Programmers think, and it will make strange and messy mistakes, the mistakes made by the compiler are often the most difficult to detect. I will pay attention to them later ~~