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: RomaniaPosts: 1697 |
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. Hobbit name: Togo Toadfoot of Frogmorton Elvish name: Mablung Miriel Beyound Arduino Lang |
||||
vasi Guru Joined: 23/03/2007 Location: RomaniaPosts: 1697 |
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. Hobbit name: Togo Toadfoot of Frogmorton Elvish name: Mablung Miriel Beyound Arduino Lang |
||||
vasi Guru Joined: 23/03/2007 Location: RomaniaPosts: 1697 |
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: AustraliaPosts: 122 |
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 KingdomPosts: 3815 |
It's not many bytes on most uC chips. Is it useful, though? John |
||||
vasi Guru Joined: 23/03/2007 Location: RomaniaPosts: 1697 |
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. Hobbit name: Togo Toadfoot of Frogmorton Elvish name: Mablung Miriel Beyound Arduino Lang |
||||
vasi Guru Joined: 23/03/2007 Location: RomaniaPosts: 1697 |
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 |