搜索
bottom↓
回复: 8

【分享】在 Arduino 当中看到了 C++流式接口

[复制链接]

出200入2554汤圆

发表于 2018-12-11 02:47:55 | 显示全部楼层 |阅读模式
本帖最后由 t3486784401 于 2018-12-11 02:44 编辑

【背景】
想必接触过 AVR 的各位都或多或少接触过 Arduino,简单说就是一个积木式平台,有着众多的代码库。
用着很高层的语法(C++)干着很底层(单片机)的工作,不求代码效率,但求效果晃瞎眼。

之前一直对于 Arduino 不屑,认为除了官方的核心板外,其他的系统/电路很难做到兼容。
事实证明太小瞧这平台了,基本上给定个能力较AVR差不多的处理器,就可以找到对应的内核,
再接下来你连的外设(传感器、驱动器、IO总线)找到对应的库就可以直接编译出结果了。


【Arduino 的呼吸灯】
闲来无事,想看看呼吸灯这样的操作有没有现成的库,结果真找着了(JLed),效果不多讲,但调用的代码着实晃瞎眼。
(至此各位可以回忆下标准 C 怎么写个呼吸灯、怎么封装个库):

  1. #include <jled.h>

  2. // breathe LED for 5 times, LED is connected to pin 9 (PWM capable) gpio
  3. JLed led = JLed(9).Breathe(2000).Repeat(5).DelayAfter(2000);

  4. void setup()
  5. {
  6. }

  7. void loop()
  8. {
  9.   led.Update();
  10. }
复制代码


这里解释下(Arduino大神请移步下一节):
Arduino 程序有两个入口点(区别于C的main):setup 和 loop,分别执行一次/永久循环。这结构我总觉得类似 Verilog 当中的 initial 和 always...
由于是 C++,故全局实例化了一个 Jled 类,然后类实例直接操作板载 LED,由后台 Update 实现呼吸灯效果。


【Fluent Interface】
本来用这个库的时候,想着无非就是调用几个类成员函数,设定速度、电平、效果就完事了,结果被那行实例定义晃瞎了。

JLed led = JLed(9).Breathe(2000).Repeat(5).DelayAfter(2000);

这行代码信息量略大,实现的功能大致为:
在虚拟引脚9上定义 JLed 类,设定一个2000ms的呼吸灯,重复呼吸5次,每次呼吸间隔熄灭2000ms

仔细想来,如果这些函数返回了类的引用,在 C++ 语法里这么写没毛病,当然你分开一行行调用设定也可以。
另外由于设定的都是属性,这些调用的先后顺序无所谓,例如把 Repeat 和 DelayAfter 换一换,不影响最终效果。这可读性真不是盖的。

在 .md 文件当中看到了这种代码风给的名称:“Fluent Interface”,直译过来就是 :“流式接口”。
搜索了下这种接口风格,是为提升代码可读性而设计的,典型的例子如 C++::iostream,那一堆 << << >> >> 符号就是重载的流式接口。
一个单片机的编译器(GNU这个组织真心不说啥了),居然标准地支持 C++ 到如此地步,说实在的让人不寒而栗。


【后记】
说到呼吸灯,哪怕是汇编也能在 M64 上码出一模一样的运行结果。但封装这个灯光库的歪果仁,恐怕不单单是为了晃瞎观众那么简单。
总之搬运过来给大家分享,如有不当之处还请各位前辈指教。

P.S.    我用了第三方的处理器 + 第四方的内核库 + 第五方的灯光库,在 Arduino 平台上居然合成了可以正确运行的 HEX 文件,真心佩服这兼容性。
P.S.2. 以下是库源文件地址,有兴趣各位可移步瞻仰:https://github.com/jandelgado/jled

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出615入1076汤圆

发表于 2018-12-11 04:10:06 | 显示全部楼层
本帖最后由 dukelec 于 2018-12-11 04:25 编辑

前两年打算为 Arduino 写一个库,看了下官方对代码组织结构的要求太操蛋了,连子目录都不给用。
自己的项目文件多了想搞一个子目录也不行,必须要安装到插件目录当作库来调用。

另外,我觉得这个例子的可读性不见得有多友好,感觉直接把这些参数传给一个 init 函数更直观,N 多个接口化简为 1 个接口。

出140入8汤圆

发表于 2018-12-11 04:25:52 来自手机 | 显示全部楼层
一天做项目就是凑个功能…很少去思考这些有点深度的问题…注定累死累活,事业也走不远

出0入442汤圆

发表于 2018-12-11 07:01:24 | 显示全部楼层
gcc其实后端是直接支持avr的。所以可以直接编译c++等。只是生成代码量可能稍大。avr,avr32,arm,mips,riscv,这几个都是支持较好的。openrisc就不行。开gc-sections就不出bin了。

出0入0汤圆

发表于 2018-12-11 08:47:07 | 显示全部楼层
刚毕业的时候就想去学C++ , 面向对象还好理解,就是有时候很郁闷,
对象.对象.对象.函数
这些函数树,说明去哪找?
找不到了..不学了丢~

出200入2554汤圆

 楼主| 发表于 2018-12-11 14:02:14 | 显示全部楼层
dukelec 发表于 2018-12-11 04:10
前两年打算为 Arduino 写一个库,看了下官方对代码组织结构的要求太操蛋了,连子目录都不给用。
自己的项目 ...

容易上手的玩意,往往深挖就麻烦

出200入2554汤圆

 楼主| 发表于 2018-12-11 14:04:09 | 显示全部楼层
leiyitan 发表于 2018-12-11 04:25
一天做项目就是凑个功能…很少去思考这些有点深度的问题…注定累死累活,事业也走不远 ...

国内这行情,想深入研究的不如会倒腾关系的

出200入2554汤圆

 楼主| 发表于 2018-12-11 14:05:30 | 显示全部楼层
wye11083 发表于 2018-12-11 07:01
gcc其实后端是直接支持avr的。所以可以直接编译c++等。只是生成代码量可能稍大。avr,avr32,arm,mips, ...

Atmel 官方的 AvrStudio 内嵌就是 GCC,看样子是找对了大后台

出200入2554汤圆

 楼主| 发表于 2018-12-11 14:07:32 | 显示全部楼层
jcrorxp 发表于 2018-12-11 08:47
刚毕业的时候就想去学C++ , 面向对象还好理解,就是有时候很郁闷,
对象.对象.对象.函数
这些函数树,说明去 ...



以前 VS 的时候用 MSDN,现在 Arduino 直接翻源码去了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 10:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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