orb*_*boy 6 c avr avr-gcc atmel atmelstudio
在调试会话期间,我发现snprintf在使用avr-gcc编译代码时无法按预期工作.示例代码应该简单地将浮点值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;
}
Run Code Online (Sandbox Code Playgroud)
使用avr-gcc编译此示例代码并使用Atmel Studio 7运行它会返回值-2.这意味着snprintf无法正常工作.
到目前为止我尝试了什么:
TestSnprintf返回值0).TestSnprintf返回值0).内容buf是
buf[0] = 32;
buf[1] = 32;
buf[2] = 32;
buf[3] = 32;
buf[4] = 32;
buf[5] = 63;
buf[6] = 0;
Run Code Online (Sandbox Code Playgroud)使用JTAG接口在器件上执行测试.我也尝试了模拟器,结果相同.
-O0.以下是调试会话的屏幕截图,它显示返回值为-2.
题
我究竟做错了什么?
解
首先,非常感谢大家的帮助!正如@manilo所指出的,缺少以下链接器选项:
-Wl,-u,vfprintf -lprintf_flt -lm
Run Code Online (Sandbox Code Playgroud)
man*_*lio 10
printf()(和朋友)有三种不同的实现方式.默认情况下不实现浮点输出.
snprintf没有链接libprintf_flt.a(-lprintf_flt)和libm.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