3

I am tracking down the memory usage of an Arduino-like project I am working on (not a real Arduino, but has same microcontroller and it uses the Arduino build environment, version 1.6.8). I have some modules that I am using and placed them in the Libraries directory in my sketch directory:

Encoder
LiquidCrystal
OneWire
TGPages
TGPro

Now, when I compile a minimal sketch...

#include <Arduino.h>

void setup()
{
}

void loop()
{
}

...the compiled size is 450 bytes Flash and 9 bytes RAM. So far, so good.

Now here's the weird part: when I include a single header file from anywhere in the Libaries folder, the compiled size increases dramatically.

#include <Arduino.h>
#include "pins.h"

void setup()
{
}

void loop()
{
}

"pins.h" is located in the TGPro directory and only contains #defines, not even code or other includes.

....
Using library TGPro in folder: C:\Users\User\Project\TG\libraries\TGPro (legacy)
Using library OneWire in folder: C:\Users\User\Project\TG\libraries\OneWire (legacy)
Using library Encoder in folder: C:\Users\User\Project\TG\libraries\Encoder (legacy)
Using library LiquidCrystal in folder: C:\Users\User\Project\TG\libraries\LiquidCrystal (legacy)
Using library EEPROM at version 2.0 in folder: C:\Users\User\Project\TG\hardware\arduino\avr\libraries\EEPROM 
Using library Wire at version 1.0 in folder: C:\Users\User\Project\TG\hardware\arduino\avr\libraries\Wire 

Sketch uses 2,266 bytes (7%) of program storage space. Maximum is 32,256 bytes.
Global variables use 230 bytes (11%) of dynamic memory, leaving 1,818 bytes for local variables. Maximum is 2,048 bytes.

And I'm like: WTF? I'm not even referencing any of the files, still they get pulled in, wasting space. There are a few global, static variables in there which explain the used space and referenced code.

So, my questions:

  1. Is het normal for Arduino to pull in all files in the Sketch\Libraries directory, regardless if they are referenced or not? It doesn't seem to do this with the 'core' libraries.
  2. How can you prevent this? Suppose I have a large collection of modules that I use in various projects, but not all modules are used all the time. It would be a waste to include code that is never actually used.
  3. How can I find out more about the code that is compiled in; I know the linker will leave out unreferenced code, but I want to make sure this is due to the statically defined variables.
  • 1
    avr-nm -C the_compiled_program.elf should tell you what's in there (your question 3). – Edgar Bonet Jul 8 '16 at 17:25
1

What you are experiencing is due to the fact that your use case does not match with the Arduino foreseen use cases of "importing a library".

Basically you want the use case "include a file" and you get "import a library". The use case "import file" is simply not foreseen in the Arduino IDE. Because the Arduino IDE add the library to your code it also adds the source doe files to your code. When these source codes contain global variables (which is very common and not a bad practise in embedded world) these will be part of your final code. As such your sketch will increase size even if you do not use these global variables.

To answer questions
1) yes it is normal because the use case "include file" is translated into "include library" in .ino files in the Arduino IDE.
Why this does not happen for the core? The core is first linked into a archive and then linked to the sketch. This leaves the linker more options to remove stuff.

2) I think the easiest is to copy the pins.h file in your sketch work folder (and you probably will need to restart the Arduino IDE).
Another option is to go for a real IDE like the arduino eclipse plugin called sloeber (which I develop)
In sloeber you could link to the pins.h file instead of copying. You could also reference the pins.h with a (partial/full) path avoinding the library include.

3) All global variables, static and similar stuff in the source code of the "imported libraries"

  • 1) I know that Arduine pulls in the source code. However, my understanding so far is that if I include, say "lcd.h", it would import "lcd.cpp" together with its includes, and so on. I do not expect (nor want) everything to be pulled in, just because the file is in a particular directory. 2a) pins.h is already in the sketch folder, under Libraries. 2b) Copying files is of course unaccaptable; that will create a versioning nightmare. The idea is to share files between projects (sketches), of course. 2c) What would sloeber accomplish? 3) yes, Edgar Bonet's comment already gave a few hints. – JvO Jul 8 '16 at 19:45
  • 1) that would be the use case "import class". I have never seen this usecase anywhere in c/c++. 2a) yes but it is there in such a way that also the c/c++ files are there. 2b) you could consider making a library only containing pins.h 2c) added 2 options to the answer. – jantje Jul 9 '16 at 12:23
  • I'm sorry this is not what you wanted as an answer. And thanks for accepting. – jantje Jul 29 '16 at 13:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.