3

* 更新 *

这是我发现的。每当我在那里拥有该功能时,它实际上不会使代码锁定。它实际上会使读取 RTC I²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²C RTC 中读取一个字节时,代码会卡住,但只要我删除它printf("index = %s\n", bTmpSms);或使用它printf("index = 2\n"); ,一切都会很开心。有任何想法吗?

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

4

7 回答 7

2

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


更新后编辑

我在本地机器上没有参考itoa,但我找到了这个(http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/)。根据该参考资料,目标数组必须足够长以容纳任何可能的值。检查您的文档:您的具体itoa情况可能有所不同。

或使用sprintf,snprintf或标准描述的某些功能。

于 2010-10-12T18:35:42.670 回答
1

一些想法:

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

pmg 有一个很好的观点。

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

于 2010-10-12T18:39:51.777 回答
1

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

这些是最难追查的问题*。祝你好运。

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

于 2010-10-12T20:20:50.820 回答
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;
}
于 2010-10-12T20:29:50.273 回答
0

bSmsIndex 的值是多少?

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

于 2010-10-12T18:37:51.810 回答
0

bSmsIndex您尝试打印的价值是什么?

如果它大于 99,那么你就超出了bTmpSms数组。

如果这没有帮助,那么使用 IAR 相当不错的调试器 - 我会在printf()被调用的地方进入程序集窗口并单步执行,直到事情进入杂草。这可能会弄清楚问题所在。

或者作为一个快速的n-dirty故障排除,尝试将阵列调整为大的(可能是8个),看看会发生什么。

于 2010-10-12T18:38:12.463 回答
0

尝试用 index = 2vs. index =来分解这个区域%s

于 2010-10-12T19:56:29.037 回答