tags:

views:

100

answers:

7

* UPDATE *

here is what I found. Whenever I had that function in there it wouldnt actually make the code lock up. what it would actually do is make the Read RTC I2C function very slow to execute but the code would still run properly, but I had to wait a really long time to get past everytime I read the RTC. so what ended up happening was that there is an alarm interrupt for the RTC and this was triggering other I2C interactions inside the ISR so what it looks like it was doing was trying to do two i2c communications at the same time therefore slowing down the process. I removed the functions in the ISR and it now its working I will keep investigating.

I am having this problem when programming an STM32F103 micro using IAR 5.40 I have this function that If I try to printf a local variable it causes the code to freeze at another point way before it even gets to that function in question.

What could possibly be causing this ??

this is the function

u8 GSM_Telit_ReadSms( u8 bSmsIndex )
{
  char bTmpSms[3] = { 0 };

  itoa( bSmsIndex, bTmpSms, 10 ); // converts the smsindex into a string

  printf("index = %s\n", bTmpSms);  //this printf caused the code to get stuck in the RTC // byte read function !!!!!!!

  GSM_Telit_RequestModem( "AT+CMGR=""1", 10, "CMGR", 5, 0 ); 
  return 1;
}

I tried this as well and this does not causes the lock I experienced

u8 GSM_Telit_ReadSms( u8 bSmsIndex )
{
  char bTmpSms[3] = { 0 };

  itoa( bSmsIndex, bTmpSms, 10 );
  printf("index = 2\n");


  GSM_Telit_RequestModem( "AT+CMGR=""1", 10, "CMGR", 5, 0 ); 
  return 1;
}

There is no optimization enabled whatsoever and the code gets stuck when trying to read a byte out of my I2C RTC, but as soon as I remove this printf("index = %s\n", bTmpSms); or use this one instead printf("index = 2\n"); then everything is happy Any ideas ???

Edit : The bSmsIndex will never be more than 30 actually and even then the lock up happens wayyyy before this function gets called.

+2  A: 

char bTmpSms[3] only has space for "99". If your bSmsIndex is 100 or greater, you will be trying to write to memory that doesn't belong to you.


Edit after the update

I don't have a reference to itoa on my local machine, but I found this one ( http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ ). According to that reference, the destination array MUST BE LONG ENOUGH FOR ANY POSSIBLE VALUE. Check your documentation: your specific itoa might be different.

Or use sprintf, snprintf, or some function described by the Standard.

pmg
Correct, but it's not the write that's causing the issue (as the second code works). It's the printf reading the string that kills things. However, the write could cause a problem at some point too, so definately an issue too
Paul
@Paul - but who knows what the errant write might be trashing?
Michael Burr
As far as I'm concerned, writing to memory that doesn't belong to you, could make your program transfer money from your bank account to mine :-)
pmg
Oh, completely agreed :)
Paul
A: 

What's the value of bSmsIndex?

If more than 99 it will be 3 digits when converted to a string. When zero terminated, it wuill be four characters but you've allocated only three to bTmpSms so the null may get overwritten and hte printf will try to print whatever uis after bTmpSms until the next null. That could access anything, really.

Paul
A: 

What's the value of bSmsIndex you're trying to print?

If it's greater than 99 then you're overrunning the bTmpSms array.

If that doesn't help, then use IAR's pretty good debugger - I'd drop into the assembly window at the point where printf() is being called and single step until things went into the weeds. That'll probably make clear what the problem is.

Or as a quick-n-dirty troubleshoot, try sizing the array to something large (maybe 8) and see what happens.

Michael Burr
I did try making the array bigger but the same problem occurred
jramirez
@jramirez: I think you may need to roll up your sleeves and start stepping into the runtime abyss...
Michael Burr
+1  A: 

Some ideas:

If itoa() is not properly NUL-terminating the string, then the call to printf may result in the machine looking for the NUL forever.

pmg has a very good point.

Also, consider what type the first argument to itoa() is. If it's signed and you're passing in an unsigned integer, then you may be getting an unexpected minus sign in bTmpSms. Try using sprintf() instead.

Matt Kane
itoa is null terminated I checked
jramirez
A: 

have you disassembled this area with index = 2 vs index = %s

dwelch
+1  A: 

The change in code is moving the rest of your code around in memory. My guess is that some other part of the code, not listed here, is bashing some random location; in the first case that location contains something critical, in the second case it does not.

These are the worst kinds of problems to track down*. Good luck.

*Maybe not the worst - it could be worse if it were a race condition between multiple threads that only manifested itself once a week. Still not my favorite kind of bug.

Mark Ransom
A: 

Alright thank you everybody you gave me some great pointers and it helped me figure it out.

It seems that if I dont initialize the variable bTmpSms to something the problem occurs also I realized that is not the printf that is the problem is the itoa function. again thanks to everybody that kept mentioning it. it got me to check that even though i didnt think that was the problem. when I commented the itoa function then the whole code works.

so what I ended up doing was this:

u8 GSM_Telit_ReadSms( u8 bSmsIndex )
{
  char bTmpSms[4] = "aaa";    // I still need to find out why this is !!!

  itoa( bSmsIndex, bTmpSms, 10 ); // converts the smsindex into a string

  printf("index = %s\n", bTmpSms);  //this printf caused the code to get stuck in the RTC // byte read function !!!!!!!

  GSM_Telit_RequestModem( "AT+CMGR=""1", 10, "CMGR", 5, 0 ); 
  return 1;
}

this is the itoa function I got I dont remember where i got it from I will check it later see if there is something i missed.

char itoa( int value, char* result, int base )
{
  // check that the base if valid
  if (base < 2 || base > 36) { *result = '\0'; return 0; }

  char* ptr = result, *ptr1 = result, tmp_char;
  int tmp_value;

  do
  {
    tmp_value = value;
    value /= base;
    *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
  } while ( value );

  // Apply negative sign
  if (tmp_value < 0) *ptr++ = '-';
  *ptr-- = '\0';
  while(ptr1 < ptr)
  {
    tmp_char = *ptr;
    *ptr--= *ptr1;
    *ptr1++ = tmp_char;
  }
  return 1;
}
jramirez
See my answer. I don't think you fixed the problem, I think you masked it. It will come back to bite you later on.
Mark Ransom
I agree with you. thats why I said I will check this function later. but at least I know where the problem is for the most part.
jramirez
I hope I'm not misunderstanding you - it sounded like the problem manifests even before the `atoi` function is called, so the bug can't be there either. You don't *really* know where the problem is.
Mark Ransom
the problem only appears when the atoi function is in there. and no it does not get there. when the function is commented out the code runs correctly so that gives some ideas where the problemis , also I am going to use sprintf( bTmpSms, "%d", bSmsIndex ) which seems to be working. again is embedded programming so it will take me a little while to step through the code find where the problem really is I will update any progress
jramirez