优化库 Arduino:未定义参考
Optimize library Arduino : undefined reference
嵌入式系统的开发强加了另一种编码方式。
为了最小化名为 RF24Wave
的库的大小,我将调整主 class 的结构。
这个想法是在将我的库包含在主程序中的过程中仅在存在某些 #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();
}
The goal is to include only master functions
when #define WAVE_MASTER
is defined in the main sketch.
然而,在编译我的主要草图时,我有一个链接错误
In function `main':
undefined reference to `RF24Wave::printNetwork()'
collect2: error: ld returned 1 exit status
*** [.pioenvs/uno/firmware.elf] Error 1
I compiled with PlaformIO Core 1.7.1 /Atom 1.13.0
最后,这个问题的原因是范围#define
。
The solution of this problem is added build flags to gcc-compiler !
If you use combo PlatformIO/Atom, you can add this line into this
config file platformio.ini
:
build_flags = -D$NAME_DEFINE
In our case :
build_flags = -DWAVE_MASTER
After adding this line, the building seems work fine !
此外,通过这种选择性 #define
,我的图书馆减少了超过 10% 的内存占用!
非常感谢您的帮助。
如果你在 arduino IDE 中添加你的库,正如它所描述的那样 here it just consists in linking another project to your library functions. It's not a static library (see static and dynamic libraries)。然后我认为没有必要担心它的大小,因为只有当你使用它们时,编译器才会嵌入你的库函数。
尝试打开任何示例(AnalogReadSerial),编译它。然后Sketch->Add a library->SPI。再次编译,大小没有变化。尝试在设置函数中调用 SPI.begin()
,大小增加。添加对 SPI.setBitOrder(MSBFIRST);
的调用,大小再次增加。添加对 SPI.setBitOrder(MSBFIRST);
的另一个调用,大小再次增加,但增加的量不同,因为它只包含一个 setBitOrder 定义和对 setBitOrder 函数的两次调用。
并非所有库都如此,因为某些结构可能会强制编译器嵌入某些代码或分配内存,即使变量未被使用(参见 volatile variables 示例)。
所以关于你的尺寸问题,你可能只需要使用一个 #define MASTER
,在设置和循环函数中写主代码,用 #ifdef MASTER
包围,从代码用 #else...#endif
。编译器将包括主从使用的函数定义。
所以,有了你的回答,我找到了解决方案!
问题是 #define
的范围。在构建过程中,第一个编译的源代码是主要草图!因此,它在 master.cpp
的 RF24Wave.h
中包含了正确的 #define WAVE_MASTER
。但是,编译器不会将此定义考虑到其他源文件。因此,在 RF24Wave.cpp
的编译过程中,没有为该源文件定义 #define WAVE_MASTER
。
解决方案包括添加一个额外的 gcc-flag 来为所有源文件和头文件定义 WAVE_MASTER
。
使用 PlatformIO/Atom,可以在配置文件中添加这一行 platformio.ini
build_flags = -DWAVE_MASTER
最后,您的配置文件应如下所示:
[env:uno]
platform = atmelavr
board = uno
framework = arduino
build_flags = -DWAVE_MASTER
使用此解决方案,不再需要在头文件中添加 #define WAVE_MASTER
,因为这是编译器为您添加的。
此外,此优化减少了超过 10% 的内存使用,因为这是一个很大的 class 对象,编译器构建了所有函数。使用选择性定义,编译器将只构建有用的函数。
嵌入式系统的开发强加了另一种编码方式。
为了最小化名为 RF24Wave
的库的大小,我将调整主 class 的结构。
这个想法是在将我的库包含在主程序中的过程中仅在存在某些 #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();
}
The goal is to include only
master functions
when#define WAVE_MASTER
is defined in the main sketch.
然而,在编译我的主要草图时,我有一个链接错误
In function `main':
undefined reference to `RF24Wave::printNetwork()'
collect2: error: ld returned 1 exit status
*** [.pioenvs/uno/firmware.elf] Error 1
I compiled with PlaformIO Core 1.7.1 /Atom 1.13.0
最后,这个问题的原因是范围#define
。
The solution of this problem is added build flags to gcc-compiler !
If you use combo PlatformIO/Atom, you can add this line into this config file
platformio.ini
:
build_flags = -D$NAME_DEFINE
In our case :
build_flags = -DWAVE_MASTER
After adding this line, the building seems work fine !
此外,通过这种选择性 #define
,我的图书馆减少了超过 10% 的内存占用!
非常感谢您的帮助。
如果你在 arduino IDE 中添加你的库,正如它所描述的那样 here it just consists in linking another project to your library functions. It's not a static library (see static and dynamic libraries)。然后我认为没有必要担心它的大小,因为只有当你使用它们时,编译器才会嵌入你的库函数。
尝试打开任何示例(AnalogReadSerial),编译它。然后Sketch->Add a library->SPI。再次编译,大小没有变化。尝试在设置函数中调用 SPI.begin()
,大小增加。添加对 SPI.setBitOrder(MSBFIRST);
的调用,大小再次增加。添加对 SPI.setBitOrder(MSBFIRST);
的另一个调用,大小再次增加,但增加的量不同,因为它只包含一个 setBitOrder 定义和对 setBitOrder 函数的两次调用。
并非所有库都如此,因为某些结构可能会强制编译器嵌入某些代码或分配内存,即使变量未被使用(参见 volatile variables 示例)。
所以关于你的尺寸问题,你可能只需要使用一个 #define MASTER
,在设置和循环函数中写主代码,用 #ifdef MASTER
包围,从代码用 #else...#endif
。编译器将包括主从使用的函数定义。
所以,有了你的回答,我找到了解决方案!
问题是 #define
的范围。在构建过程中,第一个编译的源代码是主要草图!因此,它在 master.cpp
的 RF24Wave.h
中包含了正确的 #define WAVE_MASTER
。但是,编译器不会将此定义考虑到其他源文件。因此,在 RF24Wave.cpp
的编译过程中,没有为该源文件定义 #define WAVE_MASTER
。
解决方案包括添加一个额外的 gcc-flag 来为所有源文件和头文件定义 WAVE_MASTER
。
使用 PlatformIO/Atom,可以在配置文件中添加这一行 platformio.ini
build_flags = -DWAVE_MASTER
最后,您的配置文件应如下所示:
[env:uno]
platform = atmelavr
board = uno
framework = arduino
build_flags = -DWAVE_MASTER
使用此解决方案,不再需要在头文件中添加 #define WAVE_MASTER
,因为这是编译器为您添加的。
此外,此优化减少了超过 10% 的内存使用,因为这是一个很大的 class 对象,编译器构建了所有函数。使用选择性定义,编译器将只构建有用的函数。