* 更新 *

这是我发现的。每当我在那里具有该功能时,它实际上不会使代码锁定。实际上,这会使读取RTCI²C函数的执行速度非常慢,但是代码仍然可以正确运行,但是我必须等待很长时间才能每次阅读RTC时都可以超越。

因此,RTC有一个警报中断,这是在ISR内部触发其他I²C交互,因此看起来它似乎正在尝试同时进行两个I²C通信,从而减慢了过程。我删除了ISR中的功能,现在正在工作。我将继续调查。


当使用IAR 5.40编程STM32F103微控制器时,我遇到了这个问题。我有一个功能,如果我尝试打印一个局部变量,它会导致代码在其他方面甚至在有问题的函数之前冻结。

有什么可能导致这个?

这是功能:

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岁,即使如此,在调用此功能之前,锁定也会发生。

有帮助吗?

解决方案 4

看来,如果我不将变量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

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

其他提示

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


更新后编辑

我没有提及 itoa 在我本地的机器上,但我发现了这台 http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ )。根据该参考,目的地数组 必须足够长的时间才能获得任何可能的价值. 。检查您的文档:特定的 itoa 可能是不同的。

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

一些想法:

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

PMG有一个很好的观点。

另外,考虑哪种类型的第一个参数 itoa() 是。如果它已签名并且您正在使用一个未签名的整数,那么您可能会在BTMPSMS中获得意外的减号。尝试使用 sprintf() 反而。

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

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

*也许不是最糟糕的 - 如果多个线程之间的种族条件,每周一次仅表现出一次。仍然不是我最喜欢的错误。

什么价值 bSmsIndex 您要打印吗?

如果它大于99,那么您就会超越 bTmpSms 大批。

如果那无济 printf() 被称为单步,直到杂草陷入困境。这可能会明确问题是什么。

或作为快速n-Dirty故障排除,尝试将数组尺寸尺寸为大的东西(也许8),看看会发生什么。

BSMSINDEX的价值是多少?

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

尝试用索引拆卸该区域= 2 vs. index = %s.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top