Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:34 29 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : The smallest code size with ArduinoIDE

Author Message
vasi

Guru

Joined: 23/03/2007
Location: Romania
Posts: 1697
Posted: 03:51am 24 Mar 2014
Copy link to clipboard 
Print this post

If you use Ubuntu 13.10 and have installed Arduino, then maybe you know that your Arduino use avr-gcc 4.7.2 which is a great version - it produces a highly optimized code in both speed and size. As you know, I'm mainly interested in obtaining the smallest code size possible from any compiler I use.

And anyone knows that the price paid for an "user friendly" language is the size of your code. The first method in reducing the code size and increasing the speed in Arduino IDE, is to use the direct access to the pins.

The following code (which toggle a LED on PD5 pin) gets only 624 bytes in size. Of course it's huge, but compared to the original, which is 1072 bytes, it is also a "huge" improvement. The following step would be to translate all C++ libraries into pure C, but you would be surprised to find out that few libraries are actually written in C++. Anyway, when code size starts to be an important factor, then you must consider moving to another toolchain.


[quote]
/*
  Blink
  Turns on an LED on for one second, then off for one second , repeatedly.
 
  This example code is in the public domain.
 */
 
#define cbi(PORT, BIT) (_SFR_BYTE(PORT) &= ~_BV(BIT))// clear bit
#define sbi(PORT, BIT) (_SFR_BYTE(PORT) |= _BV(BIT)) // set bit
#define tbi(PORT, BIT) (_SFR_BYTE(PORT) ^= _BV(BIT)) // toggle bit

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  sbi(DDRD, PD5);  
}

// the loop routine runs over and over again forever:
void loop() {
  tbi(PORTD, PD5); // toggle the LED on/off
  delay(1000); // wait for a second
}
[/quote]

As a comparison to the other toolchains, we get
- 156 bytes with a pure avr-gcc toolchain;
- 186 bytes with LunaAVR, an objectual programming environment which can be an excellent (amazing, I will say) replacement to Wiring language used by Arduino IDE (and to "C" language as well).

Vasi

___________
BTW, LunaAVR reserves 51 bytes of flash memory at the beginning for interrupt vectors on every program he generates, no matter if the current program needs it or not.Edited by vasi 2014-03-26
Hobbit name: Togo Toadfoot of Frogmorton
Elvish name: Mablung Miriel
Beyound Arduino Lang
 
vasi

Guru

Joined: 23/03/2007
Location: Romania
Posts: 1697
Posted: 04:07pm 25 Mar 2014
Copy link to clipboard 
Print this post

But you can go even further and skip any Arduino embedding (well, sort of):

[quote]
#define cbi(PORT, BIT) (_SFR_BYTE(PORT) &= ~_BV(BIT))// clear bit
#define sbi(PORT, BIT) (_SFR_BYTE(PORT) |= _BV(BIT)) // set bit
#define tbi(PORT, BIT) (_SFR_BYTE(PORT) ^= _BV(BIT)) // toggle bit

int main(void) {
  // initialize the digital pin as an output.
  sbi(DDRD, PD5);  
  while(1) {
    tbi(PORTD, PD5); // toggle the LED on/off
    delay(1000); // wait for a second
  }
  return 0;
}
[/quote]

And you get 480 bytes code size. But this is not Arduino anymore, and to develop pure "C" applications inside Arduino IDE is painful.

We didn't got rid of Arduino code completely. A parsing/processing is still made, header files are included and delay() function is of Arduino.
Edited by vasi 2014-03-27
Hobbit name: Togo Toadfoot of Frogmorton
Elvish name: Mablung Miriel
Beyound Arduino Lang
 
vasi

Guru

Joined: 23/03/2007
Location: Romania
Posts: 1697
Posted: 04:24pm 25 Mar 2014
Copy link to clipboard 
Print this post

So, lets try even harder

[quote]
#include <util/delay.h>
#define cbi(PORT, BIT) (_SFR_BYTE(PORT) &= ~_BV(BIT))// clear bit
#define sbi(PORT, BIT) (_SFR_BYTE(PORT) |= _BV(BIT)) // set bit
#define tbi(PORT, BIT) (_SFR_BYTE(PORT) ^= _BV(BIT)) // toggle bit

int main(void) {
  // initialize the digital pin as an output.
  sbi(DDRD, PD5);  
  while(1) {
    tbi(PORTD, PD5); // toggle the LED on/off
    _delay_ms(1000); // wait for a second
  }
  return 0;
}
[/quote]

Now we included the delay.h header to be able to use an avrlibc native function and we get 162 bytes code size. But as I said, this is not Arduino language anymore. It demonstrates only that we can write pure "C" code inside Arduino IDE if required.


Hobbit name: Togo Toadfoot of Frogmorton
Elvish name: Mablung Miriel
Beyound Arduino Lang
 
graynomad

Senior Member

Joined: 21/07/2010
Location: Australia
Posts: 122
Posted: 02:34am 28 Mar 2014
Copy link to clipboard 
Print this post

You should save a byte or two by using the hardware pin toggle feature, IIRC you write to PINx when the pin is set as an output.
Rob Gray, AKA the Graynomad, www.robgray.com
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3815
Posted: 05:56am 28 Mar 2014
Copy link to clipboard 
Print this post

It's not many bytes on most uC chips. Is it useful, though?

John
 
vasi

Guru

Joined: 23/03/2007
Location: Romania
Posts: 1697
Posted: 06:05am 28 Mar 2014
Copy link to clipboard 
Print this post

The difference between pure C and Wiring+Arduino libraries is dramatic on bigger projects! I know because I'm building my own AVR C library collection (code from around the world and my own) and I do often comparisons.

The gap between Arduino community and avrfreaks is pretty big and must be filled in a way that a transition can be as smooth as possible. Still hard to do. Accessing AVR pins for read/write is not quite user-friendly compared to LunaAVR language. Edited by vasi 2014-03-29
Hobbit name: Togo Toadfoot of Frogmorton
Elvish name: Mablung Miriel
Beyound Arduino Lang
 
vasi

Guru

Joined: 23/03/2007
Location: Romania
Posts: 1697
Posted: 06:17am 28 Mar 2014
Copy link to clipboard 
Print this post

  graynomad said   You should save a byte or two by using the hardware pin toggle feature, IIRC you write to PINx when the pin is set as an output.


Instead of PD5 should be the 5 number only but I wanted to be more visible which pin is used. The pin is set as output already.

I don't know yet "the hardware pin toggle feature".
Hobbit name: Togo Toadfoot of Frogmorton
Elvish name: Mablung Miriel
Beyound Arduino Lang
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024