Jump to content
danieldlo09

Doesn't call a function

Recommended Posts

Hi again, maybe you guys are getting tire of me by now, but i'm trying to make the exercises and all what appears on the tutorial http://www.43oh.com/2010/08/10-beginner-msp430-tutorials-and-counting/.

Well, i got 

count = contador();
for (j=1; j<count; j++){
P1OUT |= LED_L + LED_R;
delayfun();
P1OUT &= ~(LED_L + LED_R);
delayfun();
}

it turns out that, it calls the function contador() normally and it do what it has to do, but when it has to call the function delayfun(), it skip it. and both of the functions are declared

void delayfun (void);
int unsigned contador (void);
int main (void){...}
int unsigned contador (void){...}
void delayfun (void){
int i;
for (i=0; i<50000; i++){};
return;
}

I all ready tried without the return statement, and also changing the type of the function for int and putting return 0 too, even i probed the pushy_G2211.c that is in the tutorial (http://mspsci.blogspot.com/2010/07/tutorial-07-pushing-buttons.html) and it does the same thing.(Obiously i changed the msp430g2211.h to the micro of my own)

 

 

 

 

Share this post


Link to post
Share on other sites

Your question is understandable. You use a construct that has been in disuse for (correct) applications ever since the turbo button disappeared from PCs. You use an empty for loop to incur a delay, but since your loop does not have any effects your compiler is allowed to optimise it away. Since delayfun() does not contain any other statements the entire function is optimised away.

If you use Energia you could use Deay() instead, if you use CCS or IAR you could change your project settings to prevent your compiler to do this optimisation. Or use a more sane delay function, but that's probably for your next exercise...

 

Edit:

I suppose you're doing exercise 4 "Stuck in a loop"

In the comments Joerg states this

 

Joerg said...

Thank you for your great tutorial! I am using your examples with the mspgcc4 under Ubuntu and it works, but there is a little pitfall: I like to compile the sources using compiler optimization, e.g. -Os. But then your example will not work as expected. The optimized compiler will drop out the delay loop!

One simple solution is to declare the counter in the following way: volatile unsigned int count. This will prevent the compiler from dropping the delay loop.

So instead of changing your compiler settings, using the "volatile" qualifier will force your compiler to not optimise the empty loop.

Share this post


Link to post
Share on other sites

The function is probably being called, but the delay is most likely being optimized out.

 

 

The compiler is smart enough to know that for (i=0; i<50000; i++){}; does nothing. Also it maybe overflows.

 

Instead of declaring I as an int, which depending on your compiler, is unsigned or signed (I think IAR, CSS and Energia all treat it differently), you should use unsigned int. Signed int is -32766 to 32767. Unsigned int is 0 to 65535.

 

And to prevent it from being optimized out, you need to use the volatile keyword.

 

change int i; to volatile unsigned int i;

 

Also, the return isn't needed, as the function is declared as void functionname(void)

Share this post


Link to post
Share on other sites

Instead of declaring I as an int, which depending on your compiler, is unsigned or signed (I think IAR, CSS and Energia all treat it differently), you should use unsigned int. Signed int is -32766 to 32767. Unsigned int is 0 to 65535.

Unqualified int is always signed int. It is only char that has three variants (unqualified char being functionally identical to either signed char or unsigned char depending on compiler/configuration).

 

Adding volatile will force the loop to be retained but it's not the right approach and any tutorial that chooses to mention the technique should be fixed. The __delay_cycles() intrinsic is supported on all MSP430 compilers and should be introduced instead. (At 1MHz, __delay_cycles(500000UL) would delay one half second.)

 

When speaking of ranges of integral types, keep in mind the range depends on the target processor. On the MSP430 signed int range is -32768 to 32767; on 32-bit systems it's more likely to be larger.

 

In this case, because the upper bound of the loop exceeds the maximum signed int value, the test (i < 50000) will always succeed. Using unsigned int would prevent that, as would using an upper bound of 50000U which would force an unsigned comparison, but as written the function should be called (or inlined) and will turn into an infinite loop.

 

[Edit: Technically the signed 50000 wraps to become -15536. In that case the loop condition will always fail, so the loop would be removed. Overflow of signed integer values is undefined behavior, so you could get either result. mspgcc does the one I originally described, at least with the compiler flags I chose to use.]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×