[英]snprintf not working as expected with avr-gcc
During a debugging session, I found out that snprintf
is not working as expected when compiling the code with avr-gcc.在调试会话期间,我发现使用 avr-gcc 编译代码时
snprintf
没有按预期工作。 The example code should simply convert the floating point value 3999.9f
into its character representation.示例代码应该简单地将浮点值
3999.9f
转换为其字符表示。
Here is a minimal test case:这是一个最小的测试用例:
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;
}
Compiling this example code with avr-gcc and running it with Atmel Studio 7 gives a return value of -2 .使用 avr-gcc 编译此示例代码并使用 Atmel Studio 7 运行它会得到-2的返回值。 This means
snprintf
is not working.这意味着
snprintf
不起作用。
What I have tried so far:到目前为止我尝试过的:
TestSnprintf
return the value 0).TestSnprintf
返回值 0)。TestSnprintf
return the value 0).TestSnprintf
返回值 0)。 The content of buf
is buf
的内容是
buf[0] = 32; buf[1] = 32; buf[2] = 32; buf[3] = 32; buf[4] = 32; buf[5] = 63; buf[6] = 0;
The testing is performed on the device using the JTAG interface.使用 JTAG 接口在设备上执行测试。 I tried the simulator as well, with the same result.
我也尝试了模拟器,结果相同。
-O0
.-O0
编译和调试。 Here is a screenshot from the debugging session, that demonstrates that the return value is -2 .这是调试会话的屏幕截图,它表明返回值为-2 。
This demonstrates that buf
is in scope during debugging:这表明
buf
在调试期间在范围内:
Question问题
What am I doing wrong?我做错了什么?
SOLUTION解决方案
First of all thank you all very much for your help!首先非常感谢大家的帮助! As pointed out by @manilo the following linker options were missing:
正如@manilo 所指出的,缺少以下链接器选项:
-Wl,-u,vfprintf -lprintf_flt -lm
There are three different implementations of printf()
(and friends). printf()
(和朋友)有三种不同的实现。 The default doesn't implement float output.默认不实现浮点输出。
snprintf
won't work without linking libprintf_flt.a
( -lprintf_flt
) and libm.a
( -lm
).如果不链接
libprintf_flt.a
( -lprintf_flt
) 和libm.a
( -lm
), snprintf
将无法工作。
Also, according to the documentation, you have to add the linker options -Wl,-u,vfprintf
(eg here ).此外,根据文档,您必须添加链接器选项
-Wl,-u,vfprintf
(例如此处)。
The sequence of the linker flags is important: -Wl,-u,vfprintf -lprintf_flt -lm
链接器标志的顺序很重要:
-Wl,-u,vfprintf -lprintf_flt -lm
"Also note that by default the Arduino IDE does not set the AVR linker options to support floating point in the xxprintf() routines. So while that saves quite a bit of code space on the AVR builds, it means that printf() functions cannot be used for floating point output on the AVR. Floating support is included by default for the other processors." “还要注意,默认情况下,Arduino IDE 不会设置 AVR 链接器选项来支持 xxprintf() 例程中的浮点。因此,虽然这在 AVR 构建中节省了相当多的代码空间,但这意味着 printf() 函数不能用于 AVR 上的浮点输出。其他处理器默认包含浮点支持。” http://playground.arduino.cc/Main/Printf
http://playground.arduino.cc/Main/Printf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.