English 中文(简体)
STM32 printf and RTC
原标题:

* UPDATE *

Here is what I found. Whenever I had that function in there it wouldn t actually make the code lock up. It would actually make the read RTC I²C function very slow to execute, but the code would still run properly, but I had to wait a really long time to get past every time I read the RTC.

So there is an alarm interrupt for the RTC and this was triggering other I²C interactions inside the ISR, so it looks like it was trying to do two I²C communications at the same time, therefore slowing down the process. I removed the functions in the ISR and it s working now. I will keep investigating.


I am having this problem when programming an STM32F103 microcontroller 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
", 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 cause the lock I experienced:

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

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


  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 I²C RTC, but as soon as I remove this printf("index = %s ", bTmpSms); or use this one instead printf("index = 2 "); then everything is happy. Any ideas?

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

最佳回答

It seems that if I don t initialize the variable bTmpSms to something the problem occurs.

I also realized that it is not the printf that is the problem. It is the itoa function. It got me to check that even though I didn t think that was the problem, when I commented the itoa function then the whole code worked.

So I ended up doing 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
", 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:

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

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

  do
  {
    tmp_value = value;
    value /= base;
    *ptr++ = "zyxwvutsr

qponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)]; } while (value);

  // Apply negative sign
  if (tmp_value < 0)
      *ptr++ =  - ;
  *ptr-- =   ;
  while(ptr1 < ptr)
  {
    tmp_char = *ptr;
    *ptr--= *ptr1;
    *ptr1++ = tmp_char;
  }
  return 1;
}
问题回答

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.

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.

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.

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.

What s the value of bSmsIndex?

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

Try to disassemble this area with index = 2 vs. index = %s.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签