查看: 235|回复: 1

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

[复制链接]
  • TA的每日心情
    郁闷
    2019-2-15 13:51
  • 签到天数: 39 天

    [LV.5]常住居民I

    发表于 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, 下载次数: 2)

    该用户从未签到

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

    本版积分规则

    热门推荐

    KittenBot杯第六届开源硬件开发大赛启动啦
    KittenBot杯第六届开源硬
    大赛简介: 第六届开源硬件开发大赛由Arduino中文社区发起 由KittenBot冠名赞助
    求助,Due使用问题。
    求助,Due使用问题。
    如图,Due没有SPI库和Wire库。
    arduino+onenet+edp协议
    arduino+onenet+edp协议
    每次在edp.c这里报错,请问这是什么问题?(这一句本身应该没有问题的)
    一文教你选择Arduino开发板,小白进
    一文教你选择Arduino开发
    笔者在2016年接触了Arduino,跳了万条坑,行了千里弯,到今天也算是Arduino的一
    能够与arduino结合的嵌入式视觉识别模块
    能够与arduino结合的嵌入
    该视觉识别模块是我司于2018年新推出的产品,处理器采用双核MCU,面向创客以及steam
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表