Since the release of Arduino 1.0, some libraries have seen a huge increase in compiled file size. This is _not_ a fix for those. This will be taken care of the community sooner or later!
Here are a few general things you can do to get a smaller .hex file size:
Make sure the used variables are of the correct size.
Use ‘char’ instead of ‘int’ if you only need it for a short for-loop counting from 0 to 10. It is also helpful for compiler optimizations to specify the variables as good as you can. Don’t need any negative numbers? Declare your variables as ‘unsigned …’, e.g. ‘unsigned char’, ‘unsigned int’, ‘uint8_t’, ‘uint16_t’…
Supply your own main() function!
Instead of the usual
void setup(void) {
}
void loop(void) {
}
use this to save a couple of 100 bytes of FLASH. This disables ‘serial event’ code btw.
int main(void) {
init(); // don't forget this!
{
// place your setup code in here
}
while(1) {
// place your loop code in here
}
}
Using the hardware serial port
You can shave off a couple of hundred bytes by changing a few things in ‘HardwareSerial.cpp’. This applies the 1st tip to properly size and declare variables as needed.
Reduce ‘SERIAL_BUFFER_SIZE’ (both cases) to 8 or even 4.
Search for ‘struct ring_buffer’ and change ‘volatile int head’ to ‘volatile uint8_t head’, change ‘volatile int tail’ to ‘volatile uint8_t tail’.
Search for ‘inline void store_char(…)’ and replace the first part of the line starting with ‘int i = (unsigned int) …’ with ‘uint8_t i = (uint8_t) …’ and leave the remaining part as is.
On linux with avr-libc 1.7.1 or later
You can again save FLASH space (about 200 bytes), by using the built-in ’round()’ function of ‘math.h’ and disabling a #define in ‘Arduino.h’.
#if __AVR_LIBC_VERSION__ < 10701UL #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) #endif
Just add lines 1 and 3 around ‘#define round(x)…’ and you’re done. This is only effective if you actually use round(x) of course!
An Example
Compiling this example with an unmodified version of Arduino 1.0 and the ‘UNO’ board selected gives a file size of ’2596 bytes’!
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
int sensorValue = digitalRead(2);
Serial.println(sensorValue);
}
File size with the modifications (buffer size of 4) to ‘HardwareSerial.cpp’ is ’2342 bytes’.
When using your own main() function as suggested above
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
int main(void) {
init();
Serial.begin(9600);
pinMode(2, INPUT);
while(1) {
int sensorValue = digitalRead(2);
Serial.println(sensorValue);
}
}
the compiled file size is just ’2278 bytes’ !
Total savings for this test case: 318 bytes of FLASH space.
Happy hacking!
Related posts:





