Dear All,
I have been using arm complier V5 for a couple of years and it works very good actually. I finished one complete project using V5 -O3 optimization level. However, I started new project and I would like to use V6. I read some notes like how to migrate or what should I consider when I write C code which will be complied V6. I developed a very simple code just blinking a LED. It is "Hello World" code and it should work. However, it doesn't work V6 with any optimization level except -O0. I complied the code again with V5 -O3 and -Otime and it worked well.
Let me write my simple code and then explain what happens:
-----------------------------
Counter = 0;
while (1) { if (Counter < 5) { GPIOD->BSRR = GPIO_PIN_5; // Output is set and LED should give light. } else { GPIOD->BSRR = (uint32_t)GPIO_PIN_5<< 16 ; // Output is set and LED should give light. } if(Counter > 10) { Counter = 0; } }
//************************************************************************ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) // Timer 3 Interrupt subroutine It hits every 100ms. { if(htim == &htim3) { Counter++; } }
-------------------------------------------------------------------------------------
Counter increments every 100ms with Timer-3 interrupt in the related interrupt subroutine. So, every 500ms LED should be gives light and turn off again. However, it is continuously gives light and never turn off. I think that the complier optimizes the code and Counter is zero at the beginning and it never changes in While(1) loop. So the complier decided Counter won't be greater than 5 so no need to compile remaining code and it only builds “GPIOD->BSRR = GPIO_PIN_5;” line. If I change "if condition" that Counter is greater than 5 then the complier takes only "GPIOD->BSRR = (uint32_t)GPIO_PIN_5<< 16 ; " this line and removes others. So, this time LED stays off...
I complied with V6 -O0 and it worked but -O1,-O2,-Oz etc... it doesn't work. It works V5 -O3 with -Otime. So, what should I do? Is there any option that I don't know?
Most of my code run inside interrupt subroutines. Many variables are changed inside these subroutines and they are used in main loop which are not time critical. So, if V6 removes all my code like mentioned above I cannot use V6. I don't except that Arm made this kind of mistake. I am sure there are options that I haven't known yet.
Please help me about the issue.
Best Regards
Hi, I'm Product Manager Compilers - sorry to hear you've had problems with your migration to AC6 but thanks Ronan for great advice!
It looks like AC6 has managed to find a few additional ways to optimize code than the older AC5 compiler: we've worked hard for years to get you a compiler with the performance and code density you need to make your products successful. There is a downside of course, in that to give AC6 the visibility it needs to make optimization decisions, sometimes we need to be clearer in the information we give. In this case the compiler has become more sensitive to appropriate use of volatile specifiers - things which we could get away with for AC5 now become more important with AC6.
Many thanks for your feedback on our documentation, this isn't the first time that volatile (rather, missing volatile) has caused problems. We'll review our docs and see if any changes would be helpful.
Paul.