嵌入式系统的开发强加了另一种代码方式。
在最小化名为#define
的库的大小的目标中,我将调整我的主类的结构。
我的想法是在将我的库包含在主程序中时,仅在存在某些MySensor
的情况下声明某些函数。
像RF24Wave.h
这样的流行库使用这种方式来减少内存占用。
所以,我的库有两个文件:
#ifndef __RF24WAVE_H
#define __RF24WAVE_H
#include <arduino.h>
...
class RF24Wave
{
public:
/****** Common functions ******/
void begin();
#if !defined(WAVE_MASTER)
/****** Node functions ********/
void connect();
#else
/****** Master functions ******/
void printNetwork();
#endif
private:
bool synchronized = false;
}
:包含函数声明的头文件RF24Wave.cpp
#include "RF24Wave.h"
void begin()
{
//Body of my function
}
#if !defined(WAVE_MASTER)
void connect()
{
//Body of my function
}
#else
void printNetwork()
{
//Body of my function
}
#endif
:包含函数定义的源文件master.cpp
其次,我将此库包含在名为#define WAVE_MASTER
的主草图中,其中包含master.cpp
:
#include <RF24.h>
#include <RF24Network.h>
#include <RF24Mesh.h>
#include <SPI.h>
#define WAVE_MASTER
#include <RF24Wave.h>
#include "master.h"
// Configure the chosen CE, CSN pins
RF24 radio(CE_PIN, CSN_PIN);
RF24Network network(radio);
RF24Mesh mesh(radio,network);
RF24Wave wave(network, mesh);
uint32_t displayTimer = 0;
void setup()
{
Serial.begin(115200);
wave.begin();
}
void loop()
{
wave.listen();
wave.printNetwork();
}
:主草图master functions
目标是在主草图中定义
#define WAVE_MASTER
时仅包括In function `main': undefined reference to `RF24Wave::printNetwork()' collect2: error: ld returned 1 exit status *** [.pioenvs/uno/firmware.elf] Error 1
。
但是,在编译主草图时,我有一个链接错误
#define
我使用PlaformIO Core 1.7.1 / Atom 1.13.0编译
最后,出现此问题的原因是platformio.ini
。
此问题的解决方案是向gcc-compiler添加构建标志!
如果您使用combo PlatformIO / Atom,则可以在此添加此行 配置文件
build_flags = -D$NAME_DEFINE
:
build_flags = -DWAVE_MASTER
在我们的案例中:
#define
添加此行后,该建筑似乎工作正常!
此外,有了这个选择性{{1}},我的图书馆的足迹记忆减少了10%以上!
非常感谢你的帮助。
答案 0 :(得分:1)
如果您在arduino IDE中添加库,如here所述,它只是将另一个项目链接到您的库函数。它不是静态库(请参阅static and dynamic libraries)。然后我认为没有必要担心它的大小,因为编译器只有在你使用它们时才会嵌入你的库函数。
尝试打开任何示例(AnalogReadSerial),编译它。然后Sketch-&gt;添加库 - &gt; SPI。再次编译,大小不会改变。尝试在设置功能中调用SPI.begin()
,大小会增加。添加对SPI.setBitOrder(MSBFIRST);
的调用,大小再次增加。添加另一个调用SPI.setBitOrder(MSBFIRST);
,大小再次增加,但不是相同的数量,因为它只包含一个setBitOrder定义和两个调用setBitOrder函数。
对于所有库来说并不完全正确,因为一些构造可能会强制编译器嵌入一些代码或分配内存,即使未使用该变量(例如参见volatile variables)。
因此,关于您的大小问题,您可能只需要使用一个#define MASTER
,在#ifdef MASTER
包围的设置和循环函数中编写主代码,并且{{{}}包围的从代码1}}。编译器将包括主服务器或从服务器使用的功能定义。
答案 1 :(得分:0)
所以,有了你的答案,我找到了解决方案!
问题是#define
的范围。在构建过程中,编译的第一个源代码是主草图!因此,它包含#define WAVE_MASTER
RF24Wave.h
中master.cpp
的正确RF24Wave.cpp
。但是,编译器不会将此定义考虑到其他源文件。因此,在编译#define WAVE_MASTER
期间,没有为此源文件定义WAVE_MASTER
。
解决方案包括添加额外的gcc-flag以定义所有源文件和头文件的platformio.ini
。
使用PlatformIO / Atom,可以在配置文件中添加此行build_flags = -DWAVE_MASTER
[env:uno]
platform = atmelavr
board = uno
framework = arduino
build_flags = -DWAVE_MASTER
最后,您的配置文件应如下所示:
#define WAVE_MASTER
使用此解决方案,不再需要在头文件中添加use Zend\Mvc\MvcEvent;
...
$eventManager = $event->getApplication()->getEventManager();
$eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'onRoute'), -100);
,因为这是为您添加它的编译器。
此外,这种优化已经减少了超过10%的内存使用量,因为像这是一个大类对象,编译器构建了所有函数。使用选择性定义,编译器将只构建有用的函数。