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.
What is the appropriate method for submitting bug reports? I am using Code Composer Studio Version: 6.1.1.00022 on an MSP430F5529 Launchpad development board using GNU V4.8.1 (Red Hat) compiler, running on Windows 7 64-bit.
When I select the “Optimize for space rather than speed (-Os)” option, even with Optimization level = None (-O0), a simple delay function always hangs. When I look at the disassembly, the hang is clearly due to the generation of incorrect assembly code that creates an infinite loop. I tried adding an asm("NOP") inside the delay loop to try to force no optimization, and it only changes the location of the hang. This is easily repeatable by checking / unchecking the space vs. speed checkbox. When the option is unchecked the assembly code created is functional and appears exactly as expected.
This code
Hangs here, where it can clearly be seen that there is a hard (infinite) branch to the NOP instruction.
David,
Would you be willing to share your project (or at least the complete set of source and header file(s)) so we can reproduce this issue and file a bug report?
I am attaching a sample project that demonstrates the bug. The project is currently configured with "Optimize for space rather than speed (-Os)" unselected. If you build and download the code to an MSP430F5529 Launchpad development board, it will blink the LEDs. Then, open the properties, and select "Optimize for space rather than speed (-Os)", build and download again, and you will see that the code hangs inside the blocking delay. Look at the disassembly, and the bug should be obvious. Let me know if you need anything else.
With your posted example project, I was able to repeat the failure when using -Os with the gcc_msp430_4.9.14r1_364 compiler with CCS 6.1.2.David_Hunt said:I am using Code Composer Studio Version: 6.1.1.00022 on an MSP430F5529 Launchpad development board using GNU V4.8.1 (Red Hat) compiler
Note that I assume your mention of the GNU V4.8.1 (Red Hat) compiler is a typo, since the BlinkLED_Blocking_Timer.map in your posted example shows that the compiler used was actually gcc_msp430_4.9.14r1_364
I also noticed the following in your MSP430F5529LP_TIMERA2.c source file:David_Hunt said:I am attaching a sample project that demonstrates the bug
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // ---- READ ME - DEBUGGING INFO ---- // // There is a bug in CCS ver 6, where static (file scope) variables can not // be viewed in the debug watch window. It is bad programming style to make // these variables permanently global, so here is a middle-of-the-road // solution. If it is necesary to debug variables in this file, comment the // line "#define STATIC static", and uncomment the line "#define STATIC". // When you are done debugging, put it back the way it was. // #define STATIC // //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #define STATIC static STATIC uint16_t s_CurrentTick; STATIC uint32_t s_CurrentTick32;
In CCS6 to be able to display a static scope global variable in the debugger you need to use the syntax '<file name>'::<static var name>
E.g. 'MSP430F5529LP_TIMERA2.c'::s_CurrentTick
This is not a compiler bug. The variables s_CurrentTick and s_CurrentTick32 need to be qualified with the keyword volatile. This is true of any variable which is modified by an interrupt.
Thanks and regards,
-George
Just to clarify why the optimisation setting made a difference, the code in question has the delay() function calling GetTick(), where GetTick just reads the value of the global variable s_CurrentTick, where s_CurrentTick is updated by an interrupt routine:George Mock said:This is not a compiler bug. The variables s_CurrentTick and s_CurrentTick32 need to be qualified with the keyword volatile.
void delay(uint16_t ms) { static uint16_t start; start = GetTick(); while (ms >= Elapse(start, GetTick())) { asm("NOP"); } } uint16_t GetTick(void) { return s_CurrentTick; }
When the -Os option isn't used then the generated assembler has the delay() function calling the GetTick() function and the code happens to work, since each call to GetTick() reads the s_CurrentTick variable which isn't volatile qualified.
When the -Os option is used, the optimizer inlines the call of GetTick() into the delay() function, and then because the s_CurrentTick variable isn't volatile qualified the optimizer decides it can generate an infinite loop, as there is no observable modification to s_CurrentTick.
[It was counter-intuitive for selecting to "Optimize for space rather than speed (-Os)" to actually inline a function]
You are absolutely correct. These variables should have been volatile for the reasons you mentioned. Making them volatile fixes the generated code.