STM32 printf和RTC

时间:2010-10-12 18:32:33

标签: c arm printf iar stm32

*更新*

这是我发现的。每当我在那里使用该功能时,它实际上不会使代码锁定。它实际上会使读取RTCI²C函数执行起来很慢,但代码仍然可以正常运行,但每次读取RTC时我都要等很长时间才能过去。

因此,RTC有一个报警中断,这触发了ISR内部的其他I²C交互,所以看起来它试图同时进行两次I²C通信,因此减慢了进程。我删除了ISR中的功能,现在正在运行。我会继续调查。


使用IAR 5.40编程STM32F103微控制器时出现此问题。我有这个函数,如果我尝试printf一个局部变量,它会导致代码在它到达有问题的函数之前以另一种方式冻结。

可能导致这种情况的原因是什么?

这是功能:

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;
}

我也尝试了这个,这不会导致我遇到的锁定:

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;
}

在尝试从I²CRTC读取一个字节时,没有启用任何优化并且代码卡住了,但是一旦我删除了这个printf("index = %s\n", bTmpSms);或者使用这个printf("index = 2\n");,那么一切很开心有什么想法吗?

bSmsIndex实际上永远不会超过30,即使这样,在调用此函数之前锁定也会发生。

7 个答案:

答案 0 :(得分:2)

char bTmpSms[3]只有“99”的空间。如果您的bSmsIndex为100或更高,您将尝试写入不属于您的内存。


更新后编辑

我的本​​地计算机上没有itoa的引用,但我找到了这个(http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/)。根据该参考文献,目标阵列必须足够长,以获得任何可能的价值。查看您的文档:您的具体itoa可能不同。

或使用sprintfsnprintf或标准所描述的某些功能。

答案 1 :(得分:1)

一些想法:

如果itoa()没有正确地终止字符串,那么对printf的调用可能会导致机器永远寻找NUL。

pmg非常好。

另外,请考虑itoa()的第一个参数是什么类型。如果它已经签名并且您传入的是无符号整数,那么您可能会在bTmpSms中获得意外减号。请尝试使用sprintf()

答案 2 :(得分:1)

代码的更改是将剩下的代码移到内存中。我的猜测是,这里没有列出的代码的其他部分正在抨击一些随机位置;在第一种情况下,该位置包含一些关键的东西,在第二种情况下它不包含。

这些是追踪*的最糟糕的问题。祝你好运。

*也许不是最糟糕的 - 如果它是多线程之间的竞争条件,每周只能表现一次,可能会更糟。仍然不是我最喜欢的那种虫。

答案 3 :(得分:1)

似乎如果我没有将变量bTmpSms初始化为问题发生的事情。

我也意识到这不是printf的问题。这是itoa的功能。它让我检查,即使我不认为这是问题,当我评论itoa函数,然后整个代码工作。

所以我最终这样做了:

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;
}

这是我得到的itoa功能:

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++ = "zyxwvutsr

qponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz“[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;
}

答案 4 :(得分:0)

bSmsIndex的价值是什么?

如果超过99,转换为字符串时将为三位数。当零终止时,它将是四个字符,但是你只为bTmpSms分配了三个,所以null可能会被覆盖,printf将尝试打印bTmpSms之后的任何内容,直到下一个null。那可以访问任何东西,真的。

答案 5 :(得分:0)

您尝试打印的bSmsIndex的价值是多少?

如果它大于99,那么你将超越bTmpSms数组。

如果这没有帮助,那么使用IAR非常好的调试器 - 我会在调用printf()的位置进入汇编窗口,然后单步执行,直到事情进入杂草状态。这可能会弄清问题是什么。

或者作为快速排除故障的方法,尝试将数组调整为大型(可能是8个),看看会发生什么。

答案 6 :(得分:0)

尝试使用index = 2与index = %s对此区域进行反汇编。