EmbeddedRelated.com
Forums
Memfault State of IoT Report

CCS 4 question

Started by FIRAT KOCAK January 30, 2011
Hi Firat,

I just had to know. So I pasted your code into a default CCS project. It worked just as expected. I don't know why your build is optimized.

Have your view/projects turned on. Right click the project and do 'Build properties'. Goto Compiler/optimizations and make sure nothing is checked. You don't need them to start with and it will keep your life simpler as you learn.

Best, Dan.

Beginning Microcontrollers with the MSP430

Hi Dan,

I checked the optimizations section and all were unchecked. Declaring
the loop variable as volatile did the job. But i need to read more both
Msp430 and CCS documents.

Thank you very much for your help.

Firat

On 31.01.2011 01:10, Dan Bloomquist wrote:
>
> Hi Firat,
>
> I just had to know. So I pasted your code into a default CCS project.
> It worked just as expected. I don't know why your build is optimized.
>
> Have your view/projects turned on. Right click the project and do
> 'Build properties'. Goto Compiler/optimizations and make sure nothing
> is checked. You don't need them to start with and it will keep your
> life simpler as you learn.
>
> Best, Dan.



Hi OCS,

Yes, as David and you suggested, volatile declaration did the job.

Thank you very much.

Firat

On 31.01.2011 00:49, old_cow_yellow wrote:
>
> Some of your code may have vaporized because your variables are not
> volatile.
>
> --- In m... , FIRAT
> KOCAK wrote:
> >
> > Hi,
> >
> > I am a newbie to Msp430 and CCS. I installed CCS 4 and trying to learn
> > some coding Msp430 Launchpad. I modified original Launchpad code ( in
> > fact removed almost all code just adding led pins update in a loop
> ). My
> > code is so simple and includes a few line codes.
> >
> > My problem is, i successfully build the project and start debugger
> and i
> > am able to execute the code step by step. It works as expected. But
> > after closing the debugger and resetting the board( simply remove the
> > usb cable and then reconnect it ) leds are always lit. My code is below
> >
> > #include "msp430x20x2.h"
> >
> > #define LED0 BIT0
> > #define LED1 BIT6
> > #define LED_DIR P1DIR
> > #define LED_OUT P1OUT
> >
> >
> >
> > #define BUTTON BIT3
> > #define BUTTON_OUT P1OUT
> > #define BUTTON_DIR P1DIR
> > #define BUTTON_IN P1IN
> > #define BUTTON_IE P1IE
> > #define BUTTON_IES P1IES
> > #define BUTTON_IFG P1IFG
> > #define BUTTON_REN P1REN
> >
> > #define TXD BIT1 // TXD on P1.1
> > #define RXD BIT2 // RXD on P1.2
> >
> > #define APP_STANDBY_MODE 0
> > #define APP_APPLICATION_MODE 1
> >
> > #define TIMER_PWM_MODE 0
> > #define TIMER_UART_MODE 1
> > #define TIMER_PWM_PERIOD 2000
> > #define TIMER_PWM_OFFSET 20
> >
> > #define TEMP_SAME 0
> > #define TEMP_HOT 1
> > #define TEMP_COLD 2
> >
> > #define TEMP_THRESHOLD 5
> >
> > // Conditions for 9600/4$00 Baud SW UART, SMCLK = 1MHz
> > #define Bitime_5 0x05*4 // ~ 0.5
> > bit length + small adjustment
> > #define Bitime 13*4//0x0D
> >
> > #define UART_UPDATE_INTERVAL 1000
> >
> >
> > unsigned char BitCnt;
> >
> >
> > unsigned char applicationMode = APP_STANDBY_MODE;
> > unsigned char timerMode = TIMER_PWM_MODE;
> >
> > unsigned char tempMode;
> > unsigned char calibrateUpdate = 0;
> > unsigned char tempPolarity = TEMP_SAME;
> > unsigned int TXByte;
> >
> > /* Using an 8-value moving average filter on sampled ADC values */
> > long tempMeasured[8];
> > unsigned char tempMeasuredPosition=0;
> > long tempAverage;
> >
> > long tempCalibrated, tempDifference;
> >
> >
> >
> > void InitializeLeds(void);
> > void InitializeButton(void);
> > void InitializeClocks(void);
> >
> > void InitializeClocks(void)
> > {
> >
> > BCSCTL1 = CALBC1_1MHZ; // Set range
> > DCOCTL = CALDCO_1MHZ;
> > BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 8 = 1MHz
> > }
> >
> > void InitializeButton(void) // Configure Push Button
> > {
> > BUTTON_DIR &= ~BUTTON;
> > BUTTON_OUT |= BUTTON;
> > BUTTON_REN |= BUTTON;
> > BUTTON_IES |= BUTTON;
> > BUTTON_IFG &= ~BUTTON;
> > BUTTON_IE |= BUTTON;
> > }
> >
> >
> > void InitializeLeds(void)
> > {
> > LED_DIR |= LED0 + LED1;
> > LED_OUT &= ~(LED0 + LED1);
> > }
> >
> > void Delay( int dcount )
> > {
> > int iz;
> >
> > for( iz = 0; iz < dcount; iz ++ ){}
> > }
> >
> >
> > void main(void)
> > {
> > WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> >
> > InitializeClocks();
> > InitializeLeds();
> >
> > while( 1 )
> > {
> > LED_OUT &= ~( LED0 + LED1 );
> > Delay( 10000 );
> > LED_OUT |= ( LED0 + LED1 );
> > Delay( 10000 );
> > }
> >
> > }
> >
> >
> > Changing the delay count does not help. Changing build type from debug
> > to release does not help. Probably i forget or miss something but i
> > could not find out it.
> >
> > Any help is appreciated.
> >
> >
> > Best regards,
> >
> > Firat
> >
> >
> >
> >



On 30/01/11 23:47, FIRAT KOCAK wrote:
> Hi David,
>
> Honestly, after i read your message i said, "huh, that is it!" . thank
> you very much. The problem has now gone. It runs well. I had read about
> the issue "volatile" in the past messages but i have never thought it
> will happen to me :) I am still struggling to understand why compiler
> removes a local variable even though it is in use ?
>

"volatile" is very simple to understand once you realise that a compiler
does not translate your source code into target code. A compiler reads
your source code, and generates target code that has the same effect as
though it had done a direct translation, but only in respect to reading
and writing of volatile data.

Re-read the previous paragraph, as it is a big step for many people.

The compiler can totally disregard everything to do with local
variables, global variables, functions, etc. All it is interested in is
that every time your source code says it should read some volatile data,
that data is read, and that every time your source code says it should
write some volatile data, the correct value is written out.

Typically, it will do this using a rough translation as a starting point
- but only because that's the easiest way to handle the task.

In particular, if the compiler can figure out that a piece of code has
no effect on any volatile accesses, then it can remove it entirely.

Also note that that the compiler has absolutely no sense of timing - the
C language has no concept of time, only of the order of volatile
accesses. So the correctness of the compiler's job is unchanged if it
eliminates time-wasting code, or even if it adds time-wasting code
(though compilers that add extra time-wasting code don't stay on the
market very long).

For hosted environments (such as on a desktop), calls to external
library code also count as "volatile" for compilation purposes.

Another common misconception is what "optimisation" flags do. They do
/not/ enable or disable "optimisation", or command the compiler to
generate different types of code. They are just hints as to how much
effort the compiler should make in generating smaller and faster code,
and sometimes they inform the compiler about assumptions it can make
beyond the requirements of the C language (for example, you might
promise to avoid aliasing data, and let the compiler take advantage of
that promise to generate faster code).

In particular, the compiler can remove useless code even with all
optimisations disabled.
> I think i need some time to better learn and read much about the
> compiler behavior.
>
> Thank you and thanks to Bob and Dan.
>
> Firat
>
> On 31.01.2011 00:24, David Brown wrote:
> >
> > On 30/01/11 20:53, FIRAT KOCAK wrote:
> > > Hi,
> > >
> > > I am a newbie to Msp430 and CCS. I installed CCS 4 and trying to learn
> > > some coding Msp430 Launchpad. I modified original Launchpad code ( in
> > > fact removed almost all code just adding led pins update in a loop
> ). My
> > > code is so simple and includes a few line codes.
> > >
> >
> > If you are using CCS, I'd be sceptical of the compiler. Your code
> > doesn't yet make use of your global variables like "BitCnt", but be
> > aware that CCS does not initialise these to zero - in contradiction to
> > the C standards.
> >
> > > void Delay( int dcount )
> > > {
> > > int iz;
> > >
> > > for( iz = 0; iz < dcount; iz ++ ){}
> > > }
> > >
> >
> > You must declare "iz" to be volatile - if not, the compiler can remove
> > that loop entirely. It may well do so regardless of any optimisation
> > settings you may have picked.
> >
> >
On 31/01/11 00:10, Dan Bloomquist wrote:
> Hi Firat,
>
> I just had to know. So I pasted your code into a default CCS project. It
> worked just as expected. I don't know why your build is optimized.
>
> Have your view/projects turned on. Right click the project and do 'Build
> properties'. Goto Compiler/optimizations and make sure nothing is
> checked. You don't need them to start with and it will keep your life
> simpler as you learn.
>

Absolutely wrong! You will /not/ make your life simpler by learning to
write bad code that only works with particular compiler flags - you will
make it simpler by learning to write correct code from the start. You
cannot do embedded programming until you understand "volatile".
"Learning" embedded programming with optimisations disabled "so that it
works" is like learning to drive a car in only first gear, because you
can't figure out how the brakes work, so you don't want to go too fast.

Code whose correctness depends on the optimisation flags is broken code
(or a broken compiler), whether it works or not.
Another phenomenal I observed is: people often "Release" what they did not "Debug" and "Debug" what they do not intend to "Release".

Just as puzzling as "vaporized" when not "volatile".

--- In m..., FIRAT KOCAK wrote:
>
> Hi OCS,
>
> Yes, as David and you suggested, volatile declaration did the job.
>
> Thank you very much.
>
> Firat
>
> On 31.01.2011 00:49, old_cow_yellow wrote:
> >
> > Some of your code may have vaporized because your variables are not
> > volatile.
> >
> > --- In m... , FIRAT
> > KOCAK wrote:
> > >
> > > Hi,
> > >
> > > I am a newbie to Msp430 and CCS. I installed CCS 4 and trying to learn
> > > some coding Msp430 Launchpad. I modified original Launchpad code ( in
> > > fact removed almost all code just adding led pins update in a loop
> > ). My
> > > code is so simple and includes a few line codes.
> > >
> > > My problem is, i successfully build the project and start debugger
> > and i
> > > am able to execute the code step by step. It works as expected. But
> > > after closing the debugger and resetting the board( simply remove the
> > > usb cable and then reconnect it ) leds are always lit. My code is below
> > >
> > > #include "msp430x20x2.h"
> > >
> > > #define LED0 BIT0
> > > #define LED1 BIT6
> > > #define LED_DIR P1DIR
> > > #define LED_OUT P1OUT
> > >
> > >
> > >
> > > #define BUTTON BIT3
> > > #define BUTTON_OUT P1OUT
> > > #define BUTTON_DIR P1DIR
> > > #define BUTTON_IN P1IN
> > > #define BUTTON_IE P1IE
> > > #define BUTTON_IES P1IES
> > > #define BUTTON_IFG P1IFG
> > > #define BUTTON_REN P1REN
> > >
> > > #define TXD BIT1 // TXD on P1.1
> > > #define RXD BIT2 // RXD on P1.2
> > >
> > > #define APP_STANDBY_MODE 0
> > > #define APP_APPLICATION_MODE 1
> > >
> > > #define TIMER_PWM_MODE 0
> > > #define TIMER_UART_MODE 1
> > > #define TIMER_PWM_PERIOD 2000
> > > #define TIMER_PWM_OFFSET 20
> > >
> > > #define TEMP_SAME 0
> > > #define TEMP_HOT 1
> > > #define TEMP_COLD 2
> > >
> > > #define TEMP_THRESHOLD 5
> > >
> > > // Conditions for 9600/4$00 Baud SW UART, SMCLK = 1MHz
> > > #define Bitime_5 0x05*4 // ~ 0.5
> > > bit length + small adjustment
> > > #define Bitime 13*4//0x0D
> > >
> > > #define UART_UPDATE_INTERVAL 1000
> > >
> > >
> > > unsigned char BitCnt;
> > >
> > >
> > > unsigned char applicationMode = APP_STANDBY_MODE;
> > > unsigned char timerMode = TIMER_PWM_MODE;
> > >
> > > unsigned char tempMode;
> > > unsigned char calibrateUpdate = 0;
> > > unsigned char tempPolarity = TEMP_SAME;
> > > unsigned int TXByte;
> > >
> > > /* Using an 8-value moving average filter on sampled ADC values */
> > > long tempMeasured[8];
> > > unsigned char tempMeasuredPosition=0;
> > > long tempAverage;
> > >
> > > long tempCalibrated, tempDifference;
> > >
> > >
> > >
> > > void InitializeLeds(void);
> > > void InitializeButton(void);
> > > void InitializeClocks(void);
> > >
> > > void InitializeClocks(void)
> > > {
> > >
> > > BCSCTL1 = CALBC1_1MHZ; // Set range
> > > DCOCTL = CALDCO_1MHZ;
> > > BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 8 = 1MHz
> > > }
> > >
> > > void InitializeButton(void) // Configure Push Button
> > > {
> > > BUTTON_DIR &= ~BUTTON;
> > > BUTTON_OUT |= BUTTON;
> > > BUTTON_REN |= BUTTON;
> > > BUTTON_IES |= BUTTON;
> > > BUTTON_IFG &= ~BUTTON;
> > > BUTTON_IE |= BUTTON;
> > > }
> > >
> > >
> > > void InitializeLeds(void)
> > > {
> > > LED_DIR |= LED0 + LED1;
> > > LED_OUT &= ~(LED0 + LED1);
> > > }
> > >
> > > void Delay( int dcount )
> > > {
> > > int iz;
> > >
> > > for( iz = 0; iz < dcount; iz ++ ){}
> > > }
> > >
> > >
> > > void main(void)
> > > {
> > > WDTCTL = WDTPW + WDTHOLD; // Stop WDT
> > >
> > > InitializeClocks();
> > > InitializeLeds();
> > >
> > > while( 1 )
> > > {
> > > LED_OUT &= ~( LED0 + LED1 );
> > > Delay( 10000 );
> > > LED_OUT |= ( LED0 + LED1 );
> > > Delay( 10000 );
> > > }
> > >
> > > }
> > >
> > >
> > > Changing the delay count does not help. Changing build type from debug
> > > to release does not help. Probably i forget or miss something but i
> > > could not find out it.
> > >
> > > Any help is appreciated.
> > >
> > >
> > > Best regards,
> > >
> > > Firat
> > >
> > >
> > >
> > >
> >
> >
>

David Brown wrote:
>
> In particular, the compiler can remove useless code even with all
> optimisations disabled.
>
>

Hi David,
And the confusing part. On my box his code ran like expected, (the leds
are still flashing). I'm using the latest CCS4. I do not see gcc remove
code what so ever without optimization; at least, so far. As I have the
source on my machine I'll know better as time goes. But I would expect
all code to make it to the target without optimization. I know for sure
it is the case with microsoft, It has been my day job for over a decade
to code with VS and I put all kinds of useless code in during
development. It is always there. Several years ago I had a bug because
MS optimized out some important code. I have yet to enable any
optimization since. It doesn't make a lot of sense to optimize most box
code anyway.

It would have been insightful to know what Firat saw in the disassembly.

Best, Dan.

David Brown wrote:
> On 31/01/11 00:10, Dan Bloomquist wrote:
>
>> Hi Firat,
>>
>> I just had to know. So I pasted your code into a default CCS project. It
>> worked just as expected. I don't know why your build is optimized.
>>
>> Have your view/projects turned on. Right click the project and do 'Build
>> properties'. Goto Compiler/optimizations and make sure nothing is
>> checked. You don't need them to start with and it will keep your life
>> simpler as you learn.
>>
>>
> Absolutely wrong! You will /not/ make your life simpler by learning to
> write bad code that only works with particular compiler flags - you will
> make it simpler by learning to write correct code from the start. You
> cannot do embedded programming until you understand "volatile".
> "Learning" embedded programming with optimisations disabled "so that it
> works" is like learning to drive a car in only first gear, because you
> can't figure out how the brakes work, so you don't want to go too fast.
>
> Code whose correctness depends on the optimisation flags is broken code
> (or a broken compiler), whether it works or not.
>
>

Well, OK, if you say so...

Hi David,

What i understand from what you have written is that Compiler, while
targeting the code, eliminates the piece of code which is unnecessary or
time consuming if that does not contain variable(s) declared as
volatile. Right ?

In the meantime, thank you very much for the detailed information.

Best regards,

Firat

On 31.01.2011 01:52, David Brown wrote:
>
> On 30/01/11 23:47, FIRAT KOCAK wrote:
> > Hi David,
> >
> > Honestly, after i read your message i said, "huh, that is it!" . thank
> > you very much. The problem has now gone. It runs well. I had read about
> > the issue "volatile" in the past messages but i have never thought it
> > will happen to me :) I am still struggling to understand why compiler
> > removes a local variable even though it is in use ?
> > "volatile" is very simple to understand once you realise that a compiler
> does not translate your source code into target code. A compiler reads
> your source code, and generates target code that has the same effect as
> though it had done a direct translation, but only in respect to reading
> and writing of volatile data.
>
> Re-read the previous paragraph, as it is a big step for many people.
>
> The compiler can totally disregard everything to do with local
> variables, global variables, functions, etc. All it is interested in is
> that every time your source code says it should read some volatile data,
> that data is read, and that every time your source code says it should
> write some volatile data, the correct value is written out.
>
> Typically, it will do this using a rough translation as a starting point
> - but only because that's the easiest way to handle the task.
>
> In particular, if the compiler can figure out that a piece of code has
> no effect on any volatile accesses, then it can remove it entirely.
>
> Also note that that the compiler has absolutely no sense of timing - the
> C language has no concept of time, only of the order of volatile
> accesses. So the correctness of the compiler's job is unchanged if it
> eliminates time-wasting code, or even if it adds time-wasting code
> (though compilers that add extra time-wasting code don't stay on the
> market very long).
>
> For hosted environments (such as on a desktop), calls to external
> library code also count as "volatile" for compilation purposes.
>
> Another common misconception is what "optimisation" flags do. They do
> /not/ enable or disable "optimisation", or command the compiler to
> generate different types of code. They are just hints as to how much
> effort the compiler should make in generating smaller and faster code,
> and sometimes they inform the compiler about assumptions it can make
> beyond the requirements of the C language (for example, you might
> promise to avoid aliasing data, and let the compiler take advantage of
> that promise to generate faster code).
>
> In particular, the compiler can remove useless code even with all
> optimisations disabled.
>
> > I think i need some time to better learn and read much about the
> > compiler behavior.
> >
> > Thank you and thanks to Bob and Dan.
> >
> > Firat
> >
> > On 31.01.2011 00:24, David Brown wrote:
> > >
> > > On 30/01/11 20:53, FIRAT KOCAK wrote:
> > > > Hi,
> > > >
> > > > I am a newbie to Msp430 and CCS. I installed CCS 4 and trying to
> learn
> > > > some coding Msp430 Launchpad. I modified original Launchpad code
> ( in
> > > > fact removed almost all code just adding led pins update in a loop
> > ). My
> > > > code is so simple and includes a few line codes.
> > > >
> > >
> > > If you are using CCS, I'd be sceptical of the compiler. Your code
> > > doesn't yet make use of your global variables like "BitCnt", but be
> > > aware that CCS does not initialise these to zero - in contradiction to
> > > the C standards.
> > >
> > > > void Delay( int dcount )
> > > > {
> > > > int iz;
> > > >
> > > > for( iz = 0; iz < dcount; iz ++ ){}
> > > > }
> > > >
> > >
> > > You must declare "iz" to be volatile - if not, the compiler can remove
> > > that loop entirely. It may well do so regardless of any optimisation
> > > settings you may have picked.
> > >
> > >



On 31/01/11 02:49, Dan Bloomquist wrote:
> David Brown wrote:
> >
> > In particular, the compiler can remove useless code even with all
> > optimisations disabled.
> >
> > Hi David,
> And the confusing part. On my box his code ran like expected, (the leds
> are still flashing). I'm using the latest CCS4. I do not see gcc remove
> code what so ever without optimization; at least, so far. As I have the

gcc doesn't remove normally dead code if optimisation is disabled. But
the point is, it is allowed to do so if it (i.e., the compiler writers)
wanted to. In fact, if you use the -ffunction-sections option, which
technically is not an optimisation, then functions that are unused are
removed at link time. And perhaps future versions of gcc will remove
dead code even without optimisation.

> source on my machine I'll know better as time goes. But I would expect
> all code to make it to the target without optimization. I know for sure
> it is the case with microsoft, It has been my day job for over a decade
> to code with VS and I put all kinds of useless code in during

Temporary test code added during development is fine. Useless code in a
shipping version is not fine. It might be common in the world of
Windows programming with VS, but it is /not/ common in the embedded
development world. Bloated code means larger devices with more memory,
and higher costs - no serious embedded developer will do that on typical
projects (on hobby projects, or low-volume projects, the code efficiency
versus developer efficiency tradeoffs are different).

> development. It is always there. Several years ago I had a bug because
> MS optimized out some important code. I have yet to enable any
> optimization since. It doesn't make a lot of sense to optimize most box
> code anyway.
>

It makes no sense whatsoever to have a good compiler that generates
small and fast code, then cripple it by not using optimisation. It
makes no sense to produce target code that is much larger and slower
than it need be when the compiler can make huge improvements just by
adding a "-O2" switch. That's just money down the drain.

It may be that MS' compiler has a bug in its optimiser - I have seen
optimiser bugs in poor quality compilers on occasion. But without
knowing anything else about the compiler, the code, or the programmer, I
would guess the likely cause is a bug in your source code.

mvh.,

David
> It would have been insightful to know what Firat saw in the disassembly.
>
> Best, Dan.

Memfault State of IoT Report