snprintf与avr-gcc无法正常工作

时间:2016-06-14 15:06:30

标签: c avr avr-gcc atmel atmelstudio

在调试会话期间,我发现在使用avr-gcc编译代码时,snprintf无法按预期工作。示例代码应该只是将浮点值3999.9f转换为其字符表示形式。

这是一个最小的测试用例:

    int TestSnprintf(void)
    {
       const float inputValue = 3999.9f;
       /* Print with a fixed width of 6 characters (5 numbers and 1 dot).
       The buffer must have a length of 7, because snprintf appends a '\0' at the end. */
       char buf[7U] = {0, 0, 0, 0, 0, 0, 0};
       const uint8_t bufferSize = 7U;
       if(6 != snprintf(buf, bufferSize, "%06.1f", inputValue))
       {
          return -1;
       }
       if( buf[0] != '3'
            || buf[1] != '9'
            || buf[2] != '9'
            || buf[3] != '9'
            || buf[4] != '.'
            || buf[5] != '9'
            || buf[6] != '\0')
      {
          return -2;
      }

      return 0;
   }

   int main(void)
   {
     int retVal = TestSnprintf();
     return 0;
   }

使用avr-gcc编译此示例代码并使用Atmel Studio 7运行它会返回值 -2 。这意味着snprintf无效。

到目前为止我尝试了什么:

  • 我测试了32位和64位Linux上的代码,它按预期工作(TestSnprintf返回值0)。
  • 我使用Visual Studio 2015测试了代码,它按预期工作(TestSnprintf返回值0)。
  • buf的内容是

    buf[0] = 32;    
    buf[1] = 32;    
    buf[2] = 32;    
    buf[3] = 32;    
    buf[4] = 32;    
    buf[5] = 63;    
    buf[6] = 0;
    
  • 使用JTAG接口在设备上执行测试。我也尝试了模拟器,结果相同。

  • 未激活编译器优化。代码使用-O0进行编译和调试。

以下是调试会话的屏幕截图,其中显示返回值 -2

enter image description here

这表明调试期间buf在范围内: enter image description here

问题

我做错了什么?

首先非常感谢你的帮助! 正如@manilo所指出的,缺少以下链接器选项:

-Wl,-u,vfprintf -lprintf_flt -lm

2 个答案:

答案 0 :(得分:10)

printf()(和朋友)有三种不同的实现方式。默认情况下不实现浮点输出。

如果不关联snprintflibprintf_flt.a)和-lprintf_fltlibm.a),

-lm将无效。

此外,根据文档,您必须添加链接器选项-Wl,-u,vfprintf(例如http://winavr.scienceprog.com/avr-gcc-tutorial/using-sprintf-function-for-float-numbers-in-avr-gcc.html)。

链接器标志的顺序很重要:-Wl,-u,vfprintf -lprintf_flt -lm

答案 1 :(得分:-1)

“另请注意,默认情况下,Arduino IDE不会将AVR链接器选项设置为支持xxprintf()例程中的浮点。因此,虽然这样可以在AVR版本上节省相当多的代码空间,但这意味着printf( )函数不能用于AVR上的浮点输出。默认情况下,其他处理器都包含浮动支持。“ http://playground.arduino.cc/Main/Printf