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.

CCS: Code Breaks When Register Optimization is Turned *Off*

Other Parts Discussed in Thread: MSP430F6733

I've been wresting with a couple of seriously painful bugs over the past 24 hours and I'm starting to think they are both related to this central issue.

I was previously compiling some code for the MSP430F6733 in CCS v5.5 with Register Optimization (level 0). When I turned optimization off, execution sometimes got stuck in a particular "for" loop:

int i=0;
for(i=0; i<=9; i++)
{
    lcdmem[i] = ((mem[9-i] >> 4) & 0x0F) | ((mem[9-i] << 4) & 0xF0);
}

On closer examination with the debugger, I saw that the variable "i" was not being initialized to 0 at the beginning of the loop, instead taking the value of some large negative number. While single stepping through the disassembly, I discovered that a CLR.W instruction was not clearing both bytes of "i" (on the stack):

458     		int i=0;
005222:   4381 0002           CLR.W   0x0002(SP)
459     		for(i=0; i<=9; i++)
005226:   4381 0002           CLR.W   0x0002(SP)
00522a:   90B1 000A 0002      CMP.W   #0x000a,0x0002(SP)
005230:   343E                JGE     ($C$L5)
461     			lcdmem[i] = ((mem[9-i] >> 4) & 0x0F) | ((mem[9-i] << 4) & 0xF0);
        $C$L1:
005232:   403F 0009           MOV.W   #0x0009,R15
005236:   811F 0002           SUB.W   0x0002(SP),R15

Neither the instruction at 0x5222 nor the one at 0x5226 were actually clearing two bytes of stack - only the byte at SP+2 was cleared, with the byte at SP+3 remaining untouched.

When Register Optimization is re-enabled, the variable "i" is stored in a register instead of the stack and is cleared properly at the beginning of this loop.

My first thought was that the byte of RAM at SP+3 was malfunctioning and hence not getting updated properly. However I was able to change that byte with the debugger, and I also witnessed that byte being changed to other values by different parts of the code.

I would greatly appreciate some guidance on this issue, either as suggestions of the cause or suggestions on next debugging steps. I realize that these types of bugs are often user error rather than hardware issues, but at the moment I can't find any other explanation!

  • The compiler issued the correct instruction, and the assembler encoded it correctly.

    Here are some things to check on: Has the stack overflowed?  Is SP misaligned on an odd address? Is the memory interface configured to handle a 16-bit memory write command from the CPU?

    Thanks and regards,

    -George

  • Thanks for the quick reply George! I'm confident that the stack is not overflowing - it's a tiny program, and I filled the top of the stack area with a certain value to keep an eye on usage.

    However, SP is odd when I break at that point. In fact, SP has a value of 0x2B7B before the first instruction of main(). What could this indicate?

    EDIT: Had my hex math wrong the first time around. Edited question to correct this.

  • The SP should always be even.  See the section titled Stack Alignment in the MSP430 Embedded Application Binary Interface document.

    The routine that sets up the C environment is called the boot routine.  It has a name that starts with "_c_int00".  Please step through the boot routine (probably not that long) to see where the SP becomes odd.

    Thanks and regards,

    -George

  • It looks like the SP begins as an odd number. This is the first instruction of _c_init00:

            _c_int00, _c_int00_noexit:
    0060d2:   4031 2B7D           MOV.W   #0x2b7d,SP

    I think I found the issue - I had specified the stack size as an odd number in the CCS Linker Options menu. After incrementing the stack size by 1, the program worked.

    Thanks for all of your help. If there is a hard, low-level constraint that the SP be even, I'm surprised that CCS allows us to specify an odd stack size with no warnings. My program does use a RAM ISR table located at the bottom of RAM, so maybe that contributed to the issue?

  • Jacob Dickinson said:
    I had specified the stack size as an odd number in the CCS Linker Options menu.

    The linker should handle that better.  Maybe issue a diagnostic, or maybe add one to the stack size, or something.  I filed SDSCM00050798 in the SDOWP system to have this addressed.  Thank you for letting us know.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • Thanks for your help George! I'll keep an eye on the issue report.