lpcware

optimization problem

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by markr on Wed Oct 30 13:13:20 MST 2013
I've run into a problem that I believe is a compiler optimization problem. I'm using an LPC-812 on a breakout board that does not support either JTAG or SWD, so debugging this has been interesting. I'm using LPCXpresso v6.0.2 Build 151 2013-09-18. The code in question is:

...set-up a bunch of things, including clocks, ISR handles, pins etc, then...
while (1)                                /* Loop forever */
  {
  while(!LPC_GPIO_PORT->W0[ISP_PIN]) ; // wait on ISP button press
  while (TimeTick <= change_pwm); //wait for the counter to advance
  TimeTick=0;
#ifdef DBG_OUTPUT
  printf("R=%3d, G=%3d, B=%3d\n\r",red_pwm,green_pwm,blue_pwm);
#endif
  NOTPORT0(PORT0_BIT6); // toggle pin
//  printf("%2d",color);
  switch (color) {
... several cases: with breaks, a default, then end of the while(1).


All code from the switch() on-wards does not appear to be getting executed. The switch has several cases, each case has several tests and modifies global variables that are used in ISRs. The end of the switch is the end of the while(1).

If either printf() shown above is enabled (either enable the #ifdef or remove the comment), the switch operates correctly. If neither one is present, the code in the switch is never executed. If a printf() is placed in _any_ of the case statements, the switch executes and all cases operate correctly.

I know the processor is not off in the weeds because:
- There are pin toggles in 2 timer ISRs that keep toggling.
- The NOTPORT0 toggles a pin and that pin toggles correctly, so the primary while loop appears to be functioning correctly.
- The pin toggled by the NOTPORT0 stops toggling when the ISP button is pressed (as would be expected) and the ISRs keep running (as also expected and evidenced by pin toggles). And the pin controlled by the NOTPORT0 resumes toggling when the button is released (again as expected.)

Everything else appears to be operating correctly, just the entire switch structure is never executed! I chased this for most of a day (debugging w/o a debugger is fun!) until I started changing the optimization.

The project was initially set with size optimization (-Os) I changed to none (-O0), cleaned and rebuilt and it worked. Change it back to size (-Os), clean and rebuild and it doesn't work. There is definitely something bad going on with optimization. (I haven't tried the other levels yet.)

Besides the problem noted above, it appears that just changing the optimization level does not cause a re-build of the project. The code remains working or not working, irrespective of the optimization setting. Only if I change the optimization _and_ touch the code (add/delete a space and save) and recompile, does the behavior change. A clean and rebuilt does generate new code and will cause it to work or not work, depending on the state of the code and optimization.

The need to clean and rebuilt when changing optimization is not that surprising and is a minor nuisance. But having optimization remove most of main() is another issue.

I'm new to LPCXpresso and ARM in general, but have been using other micro-controlllers and IDEs for years. I'll admit I don't know LPCXpresso well enough to generate assembly and look at the resulting intermediate code. (It took some wrangling to get it to output a hex file for Flash Magic.)

Any thoughts or suggestions would be appreciated.

-markr

Outcomes