Hi, I've been working with keil uvision 4 for almost 3 years or more, coding for Cortex-M3. I recently bump into a problem while testing my code. For some crazy reason a function of my doesn't work unless I declare the variables as statics. And I say it is crazy because it only happens in one function. If I get the same code inside the function and put in main() it works perfectly, without being necessary to declare the variable as static. No optimization is done. Hope one of you guys could help me. Otherwise I'll have to start declaring all local variables as "static". Best regards, Rodrigo Barros
PS: the function is described bellow.
//This function works void func2(int *x, int *y) { uint32_t a[1024]; uint8_t buffer[64]; a[1000] = *x; a[1023] = *y; //send_msg() sends a msg through USB send_msg("\rfunc2 begin.\n\0", strlen("\rfunc2 begin.\n\0")); for(a[1000] = 0; a[1000]< 5; a[1000]++) { sprintf( (char *) buffer, (char *)("func2 1.%i.\0"), a[1000]); send_msg( buffer, strlen(buffer) ); cleanBuffer(buffer, 64); delay(100 MHZ, 0.5); //wait for 500ms } for(a[1023]=0; a[1023]<5; a[1023]++) { sprintf( (char *) buffer, (char *)("func2 2.%i.\0"),a[1023]); send_msg( (char *) buffer, (char *) strlen(buffer) ); cleanBuffer(buffer, 64); delay(100 MHZ, 0.5); //wait for 500ms } send_msg("\rfunc2 end.\n\0", strlen("\rfunc2 end.\n\0")); } //This function doesnt work void func1(void) { uint8_t buffer[64] = {}; static uint32_t a = 0; uint32_t b = 0; send_msg("\rfunc1 begin.\n\0", strlen("\rfunc1 begin.\n\0")); for(a = 0; a < 5; a++) { sprintf( (char *) buffer, (char *)("func1 1.%i.\0"), a); send_msg( buffer, strlen(buffer) ); cleanBuffer(buffer, 64); delay(100 MHZ, 0.5); } for(b=0; b<5; b++) { sprintf( (char *) buffer, (char *)("func1 2.%i.\0"), a); send_msg( buffer, strlen(buffer) ); cleanBuffer(buffer, 64); delay(100 MHZ, 0.5); } send_msg("\rfunc1 end.\n\0", strlen("\rfunc1 end.\n\0")); } int main(void) { char data_received; init_hardware(); while(1) { data_received = read_byte_from_serial(); switch(data_received) { case 0x00: { func2(); // This will print all the // messages 10 messages from the // two for() loops func1(); // This one will only print the // messages with the interator // which variable is static (a). // When it gets to the second for() // loop it olny increments one time... // and than get stucked forever inside // the loop. } break; //switch case continues } } //main() continues }
Otherwise I'll have to start declaring all local variables as "static".
That'd be crazy.
Have you tried single stepping through the assembler, or looking at the assembler output of the function in question, to see precisely what is happening?
I'd not even mention something as a compiler bug until this critical step has been carried out.
How large of a stack have you allocated?
What is the output of the test program?
Post a complete zipped project.
func2() consumes ~4200 bytes of stack. As Pier suggested, check your stack settings.
Thank you for your answer!
So, I'm thinking on a way to "single stepping through the assembler", because this is just a part o bigger project. Unfortunately I can't post the whole project. My application depends on a USB msg received and a software integration, if I try to debug it with U-Link it doesn't work. And its funny because just this part of the code that is causing me trouble. In the same module I have other functions that have local variable that work perfectly. I'll try to peform the single stepping debug today, and reply here again.
Best regards, Rodrigo Barros
Guys, Problem solved!!! I manage to find the problem. The buffer was set to have a size of 60 char. But I was calling the function cleanBuffer(), and passing the size as 64. So I was cleaning much more than just the buffer. Using the step debugger I was able to find the problem. Thank you all. Best regards, Rodrigo Barros
In your posted code, buffer is [64] in both functions.
Anyway - there is a reason why "magic numbers" are disliked in source code. sizeof() can often be used. And
enum { SEND_BUF_SIZE = 64, }
is also a good strategy to make sure that multiple parts of the code agrees on the same actual value.