【原创】更改编译选项使Arduino支持 %f 打印-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5625|回复: 1

【原创】更改编译选项使Arduino支持 %f 打印

[复制链接]
发表于 2019-2-11 19:49 | 显示全部楼层 |阅读模式
本帖最后由 t3486784401 于 2019-2-11 19:49 编辑

【背景】
用过 Arduino 的朋友,恐怕对于 dtosrtf 函数并不模式,专用于打印浮点数。但是实际使用过程中灵活性很受局限,
例如打印 “Value= 3.1415 (dec)”这么一串,再用 dtostrf 就不是简单一两句话就有了。

怀着对标准 C 的思念,尝试使用 sprintf 函数打印上述内容,结果发现 %f 格式不支持,明明 %d %s %c 都支持好好的。
故障现象为:sprintf 其他内容都正确,唯独 %f 控制符时,无法输出数值,显示“?”.

查了很多资料,包括 Arduino.cc 原网站的内容,发现上述膈应人的设定是用于减少整体程序尺寸,
GCC 当中提供了若干个版本的 printf/sprintf,在大尺寸版本下还是有可能支持 %f 的。于是有了本文的测试和试验。

【分析过程】
在 stdio.h 文件中,查看 printf 版本控制,发现注释当中的确存在对于 %f 格式的说明:
  \arduino-1.8.3\hardware\tools\avr\avr\include\stdio.h

  1. /*
  2. If the full functionality including the floating point conversions
  3. is required, the following options should be used:
  4. \code
  5. -Wl,-u,vfprintf -lprintf_flt -lm
  6. \endcode
  7. */
复制代码

很显然如果能正确更改 GCC 的 MAKEFILE,就可以开启该控制开关。
这个功能我在 ICCAVR 当中是可以设置项目属性来指定的,在 Arduino 当中实在太傻瓜式了,都不知道去哪改。

在整个 Arduino 目录下找到了 platform.txt,其中发现了 MAKEFILE 的原型模板。
  \arduino-1.8.3\hardware\arduino\avr\platform.txt
  1. # Default "compiler.path" is correct, change only if you want to override the initial value
  2. compiler.path={runtime.tools.avr-gcc.path}/bin/
  3. compiler.c.cmd=avr-gcc
  4. compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects
  5. compiler.c.elf.flags={compiler.warning_flags} -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections
  6. compiler.c.elf.cmd=avr-gcc
  7. compiler.S.flags=-c -g -x assembler-with-cpp -flto -MMD
  8. compiler.cpp.cmd=avr-g++
  9. compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto
  10. # These can be overridden in platform.local.txt
  11. compiler.c.extra_flags=
  12. compiler.c.elf.extra_flags=
  13. compiler.S.extra_flags=
  14. compiler.cpp.extra_flags=
  15. compiler.ar.extra_flags=
  16. compiler.objcopy.eep.extra_flags=
  17. compiler.elf2hex.extra_flags=
复制代码

按着文件里的注释,知道了可以建立 platform.local.txt 文件改写默认配置。
于是建立 platform.local.txt 文件,并指定了 stdio.h 当中提到的编译选项:
  1. # %f support for printf/sprintf
  2. compiler.c.elf.extra_flags=-Wl,-u,vfprintf -lprintf_flt -lm
复制代码


再次编译带 %f 的 ino 文件,居然真的改变了编译输出尺寸,烧录后 %f 工作正常。

加入文件前后,编译 %f 源文件输出对比:
1_Built_NoFLT.png

2_Built_FLT.png

加入文件后,%f 可以正常工作:
3_Print.png

【解决方案】
附件解压出 platform.local.txt,拷贝到 Arduino 安装目录下 \arduino-1.8.3\hardware\arduino\avr

附件: [Arduino-%f-编译支持].rar (173 Bytes, 下载次数: 136)


【测试比对】
加入上述文件、去除文件(或者重命名为其他)前后,分别编译测试代码,可以看到编译尺寸区别,运行就知道效果了。
如果希望还原原来 Arduino 配置,直接删除该 platform.local.txt 文件即可。

附上测试代码,简单打印 %f: FloatTest.rar (281 Bytes, 下载次数: 44)


后话:关于这个编译配置的修正,欢迎大家测试,如有不妥欢迎指正!

发表于 2019-2-11 20:59 | 显示全部楼层
不错啊,很有意思的方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 11:55 , Processed in 0.075255 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表