This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Optimization issues CCS 5+6 already with level 0 ! Potential safety issue for applications?

Other Parts Discussed in Thread: MSP430G2553

I am deeply disappointed by the CCS compiler for MSP430! Reason is I spend the last days in resolving an issue which root cause lies in the code optimization. 

The optimization level was only set to "0" - you would expect no big impact to the code. Wrong!

Already this setting creates difficulties with the generated code. See yourself, this is the code compiled with optimization turned finally OFF. On the left hand side you see the C code, right hand side the assembly code. The green highlighted instruction on line 888 is the one that will later be "optimized"

Now the optimized code, same location. I highlighted two instructions on the left hand side. On the assembly side you see that only one instruction is present. The important if condition is missing completely! 

Now, taking an even closer look, the missing condition in the C code is line 888. Interestingly, the debugger can not even correlate an instruction on the assembly side to this line number. That means the system COULD detect that mistake in optimization and prevent the code from being corrupted!

Looking at the whole scenario from an other side, how safe can be a program compiled with that compiler setting? Disappearing instructions and conditions already at level 0? Wow, do we need now to scan through the assembly code before we can trust the program???

Affected versions: CCS5.5, CCS6.01, compiler TI v4.4.2, 4.3.3, device MSP430 G2553

  • What does the else part of the test do? (it is just often the bottom of your screen captures)

    I was trying to work-out if the generated assembler is incorrect, or just if the generated assembler has been re-ordered without producing an incorrect result.

    [At optimization level zero the compiler is documented as performing "Register Optimizations" which can sometimes confuse debugging]

  • The full code of the section, it is located in the Watchdog timer interrupt routine:

    	if (status!=SHUTDOWN)
    	{
    		if (((P1IN & ON_PIN) == 0) && ((int_stat&1)>0))					// Button still pressed?
    		{
    
    			if ((status == CAPTURE) || (status == CAPTURE_INIT))		
    			{
    				status = EXIT_CAPTURE;
    			}
    			else if ((status == TRANSMIT) || (status == TRANSMIT_INIT))		
    			{
    				status = EXIT_TRANSMIT;
    			}
    			else if (status == ON_STATE)
    			{
    				status = SHUTDOWN;
    			}
    			else
    			{
    				status = ON_STATE;
    			}
    			__bic_SR_register(LPM3_EXIT); // Exit Sleepmode 
    			__bic_SR_register(LPM4_EXIT);
    			onState = 0;
    		}
    	}
    
        int_stat &= 0b11111100;				// reset on/off + transmit event status
    

  • Juergen Perthold said:
    The full code of the section, it is located in the Watchdog timer interrupt routine:

    Are you able to post a complete project which demonstrates the problem?

    I created a project for a MSP430G2553 with the example code fragment and comparing the assembler listing for optimization level off .vs. optimization level zero can see:

    a) With optimization level zero updates to the status variable are stored in the register r15 before finally being written to the status variable.

    b) With optimization level zero the debugging information in missing lines for the if conditional tests on the status variable.

    I.e. can see that optimization level zero would confuse single stepping in the debugger, but can't see that incorrect assembler has been produced by the compiler [I used MSP430 compiler v4.2.2]

  • Do you need just the .c and .h files or the whole project folder?

  • Juergen Perthold said:
    Do you need just the .c and .h files or the whole project folder?

    The whole project folder would be better, since that then contains all the CCS project properties (some of which set the compiler options).

  • This discussion is more relevant in the compiler forum so I will move this thread there.

    Thanks
    ki
  • e2e.zip Zipped Project Folder. The code part is at the end of the watchdog timer interrupt routine.

  • Using any optimization at all has the risk of confusing the debugging information, and I think that's what has happened here. In your "optimized code" screenshot, the code corresponding to the if condition highlighted in yellow is at addresses d16e through d17a, and the setting of the variable "status" is at address d17c, despite the fact that the text line 890 appears above address d16e. I haven't found an error in the generated assembly code. Aside from the misleading mixed view, what symptom were you experiencing? Was the code not running correctly?

  • The code was not running correctly. Was uploaded to the Launchpad by CCS 5.5 and was not executing as it should. When I started looking into it. Took 3 days to realize that maybe the compiler or CCS was creating crap. Updated from CCS5.5 to CCS6. Problem was still present. 2 more days of pulling hair, assumed that code did some mistakes in one of the interrupts. When turned on assembler to step through the program. At the critical section the condition from C source was not in assembler. Digged through compiler settings to find that optimizer was (preset?) to 0. Turned off, assembler code showed missing instructions, program was now operating as expected.

  • I'm sorry for the effort you've spent, but I think the debugging issue might be a false lead. I'm just not seeing where the program has gone wrong. Are you sure it's in this part of the code? What are the conditions (variable values, etc) coming into the symptom, what did you expect to happen, and what actually happened?
  • The problem was that no matter what the status was entering this block it always set the status to the value of EXIT_CAPTURE . Therefore the main loop/state machine was not operating correctly.

    Status translated to number:
    CAPTURE = 3
    CAPTURE_INIT = 2
    EXIT_CAPTURE = 4

    Looking at the assembler code it actually has the check for status=3 or status=2 in there (starts at D16E). But look at D16E and D176. Both instructions should compare the number 2 and 3 with status variable. However, if you look now at the machine code I miss the number 2 in the compare instruction for status=2:

    compare with 3: 90F2 0003 02F2
    compare with 2: 93E2 02F2

    Also the opcode is different even though it is disassembled both times to CMP.B
  • Juergen Perthold said:
    Looking at the assembler code it actually has the check for status=3 or status=2 in there (starts at D16E). But look at D16E and D176. Both instructions should compare the number 2 and 3 with status variable. However, if you look now at the machine code I miss the number 2 in the compare instruction for status=2:

    compare with 3: 90F2 0003 02F2
     compare with 2: 93E2 02F2

    The MSP430 has a constant generator to reduce code size, and the constant generator can generate the value 2 (but not 3) which is what I think explains the difference in the opcode.

    Also, looking back at your original screen shot of the working code with optimization off and the non-working code with optimization level zero both had the these same differences in the opcodes for comparing the status register against the values 2 and 3. i.e. don't think this is the cause of your problem.

    Juergen Perthold said:
    The problem was that no matter what the status was entering this block it always set the status to the value of EXIT_CAPTURE .

    Looking at the generated assembler with optimization level zero, I still can't see what in the generated assembler could cause that. Therefore, need to singe step the assembler on an actual device to check what happens.