代码之家  ›  专栏  ›  技术社区  ›  jramirez

stm32 printf和rtc

  •  3
  • jramirez  · 技术社区  · 15 年前

    *更新*

    这是我发现的。每当我在里面有这个函数时,它实际上不会使代码锁定。它实际上会使read rtc ic函数的执行速度非常慢,但代码仍然可以正常运行,但每次读取rtc时,我都要等很长时间才能通过。

    因此,有一个针对RTC的警报中断,这触发了ISR内部的其他IC交互,因此看起来它试图同时进行两个IC通信,因此减慢了进程。我删除了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;
    }
    

    没有启用任何优化,当试图从IC RTC中读取一个字节时,代码会卡住,但一旦我删除了它 printf("index = %s\n", bTmpSms); 或者用这个来代替 printf("index = 2\n"); 那么一切都是幸福的。有什么想法吗?

    实际上,bsmsindex永远不会超过30,甚至在调用此函数之前,锁定会一直发生。

    7 回复  |  直到 8 年前
        1
  •  2
  •   pmg    15 年前

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


    更新后编辑

    我没有提到 itoa 在我的本地机器上,但我找到了这个( http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ )根据该引用,目标数组 对于任何可能的值都必须足够长 . 检查您的文档:您的特定 伊托阿 可能不同。

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

        2
  •  1
  •   Matt K    15 年前

    一些想法:

    如果 itoa() 如果nul未正确终止字符串,则对printf的调用可能会导致计算机永久查找nul。

    PMG有一个很好的观点。

    另外,考虑第一个参数的类型 ITOA() 是。如果它是有符号的,并且您传递的是无符号整数,那么在btmpsms中可能会得到意外的减号。试用使用 sprintf() 相反。

        3
  •  1
  •   Mark Ransom    15 年前

    代码中的变化是在内存中移动其余代码。我的猜测是代码的其他部分(这里没有列出)正在攻击某个随机位置;在第一种情况下,该位置包含一些关键的内容,在第二种情况下则不包含。

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

    *也许不是最糟糕的——如果是多个线程之间的争用条件(每周只出现一次),情况可能会更糟。还是不是我最喜欢的那种虫子。

        4
  •  1
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    如果我不将变量btmpsms初始化为某个值,就会出现问题。

    我也意识到问题不在打印纸上。它是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
    

    qponmlkjihgfedcba9876543210123456789 abcdefghijklmnopqrstuvwxyz“[35+(tmp_value-value*base)]; }while(值);

      // Apply negative sign
      if (tmp_value < 0)
          *ptr++ = '-';
      *ptr-- = '\0';
      while(ptr1 < ptr)
      {
        tmp_char = *ptr;
        *ptr--= *ptr1;
        *ptr1++ = tmp_char;
      }
      return 1;
    }
    
        5
  •  0
  •   Michael Burr    15 年前

    有什么价值 bSmsIndex 你想打印吗?

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

    如果这不起作用,那么使用IAR非常好的调试器-我将在 printf() 被召唤,一步一步,直到一切都化为乌有。这可能会说明问题所在。

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

        6
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    bsmsindex的价值是什么?

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

        7
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    试着用索引分解这个区域= 2 与索引= %s .