Suprised about the blink sketch size

I just noticed the size of the ‘Blink’ example:

Binary sketch size: 1,082 bytes (of a 30,720 byte maximum)

Then I checked what was in my (cleaned) build folder; see the attached image

What?? Almost 1.1 k to blink a led? Could somebody please explain this to me?

What?? Almost 1.1 k to blink a led?

But it doesn't take 2.2k to blink two LEDs.

AWOL:

What?? Almost 1.1 k to blink a led?

But it doesn't take 2.2k to blink two LEDs.

I was hoping on a more intelligent response :(. I have a degree in computer science, i know about compilers, linkers, assemblers. But i'm really surprised at what complexity lies behind digitalWrite() and delay(), that it requires 1k to function.

The other side of this question: is there a way to finetune base library? Should i use bit banging?

Please, no suggestions for assembly or PIC, i'm passed that.

Regards, and thank you for your time,
Rob.

But it doesn’t take 2.2k to blink two LEDs.

Good response.


But really, the Arduino libraries are designed to simplify things for you. In the background a timer is set up to run so you can use delay() and millis(). Also digitalWrite and pinMode take variables as arguments which necessitates a table to be included so the ports can be looked up at runtime.

If you skip all that you can blink an LED (rather quickly) with 178 bytes of program code.

int main (void)
  {
  DDRB |= bit (5);  // pinMode (13, OUTPUT);
  while (true)
    {
    PORTB |= bit (5);  // digitalWrite (13, HIGH);
    // delay somehow here
    PORTB &= ~bit (5);  // digitalWrite (13, LOW);
    }  
  }

The processor has 26 interrupt vectors at the start of program memory, so at 4 bytes each that is 104 bytes straight away taken up. So my example blinks the LED in an additional 74 bytes, which includes code always included by the compiler to initialize RAM variables from PROGMEM.

The code for “main” above is actually:

000000a6 <main>:
  a6:	25 9a       	sbi	0x04, 5	; 4
  a8:	2d 9a       	sbi	0x05, 5	; 5
  aa:	2d 98       	cbi	0x05, 5	; 5
  ac:	fd cf       	rjmp	.-6      	; 0xa8 <main+0x2>

So actually, you can blink an LED in 8 bytes.

I have a degree in computer science,

Me too.
Well, there's crt0, the invisible "init()" function, the interrupt vector table...

Bit-banging I normally associate with serial I/O.
You could try direct port manipulation if you don't want portability

Thank you, Awol and Nick.

But really, the Arduino libraries are designed to simplify things for you. In the background a timer is set up to run so you can use delay() and millis(). Also digitalWrite and pinMode take variables as arguments which necessitates a table to be included so the ports can be looked up at runtime.

Great info, this what i was looking for. I thought they were actually calculated at compile time.

Knowing this, an at2313 leaves me only 1k of headroom, which is indeed very little. I've ordered some 328p's as well just to simplify stuff and not optimize prematurely.

Let me give you a counter example. This code (using the BigNumber library):

// BigNumber test: factorials
#include "BigNumber.h"

void setup ()
{
  Serial.begin (115200);
  while (!Serial) ;
  delay(500);
  Serial.println ();
  BigNumber::begin ();  // initialize library
 
  //factorials
  BigNumber fact = 1;

  for (int i = 2; i <= 200; i++)
  {
    Serial.print(i);
    Serial.print("! = ");
    fact *= i;
    Serial.println(fact);
  }

}  // end of setup

void loop () { }

Compiles into 8,678 bytes.

Binary sketch size: 8,678 bytes (of a 32,256 byte maximum)

Output:

2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000
16! = 20922789888000
17! = 355687428096000
18! = 6402373705728000
19! = 121645100408832000
20! = 2432902008176640000
21! = 51090942171709440000
22! = 1124000727777607680000
23! = 25852016738884976640000
24! = 620448401733239439360000
25! = 15511210043330985984000000
26! = 403291461126605635584000000
27! = 10888869450418352160768000000
28! = 304888344611713860501504000000
29! = 8841761993739701954543616000000

198! = 19815524305648002601818171204326257846611456725808373449616646563928629396065410626138298593265945324225558093942704493222553838950820027765375040827960551033001579328411138624055200727234232302046524227142061137986535960488148111891395081467526982493475408477527124840709196781511817187496273890924527108598562553359394406400000000000000000000000000000000000000000000000
199! = 3943289336823952517761816069660925311475679888435866316473712666221797249817016714601521420059923119520886060694598194151288213951213185525309633124764149655567314286353816586186984944719612228107258321201270166459320656137141474266387621212037869516201606287027897843301130159520851620311758504293980894611113948118519486873600000000000000000000000000000000000000000000000
200! = 788657867364790503552363213932185062295135977687173263294742533244359449963403342920304284011984623904177212138919638830257642790242637105061926624952829931113462857270763317237396988943922445621451664240254033291864131227428294853277524242407573903240321257405579568660226031904170324062351700858796178922222789623703897374720000000000000000000000000000000000000000000000000

Only 8k of code to output factorial 200 on a tiny 8-bit processor with only 2 kB of RAM.

On my Mac, the “hello world” sketch takes 8,696 bytes, so … what can you do?

RobvdVeer:
Knowing this, an at2313 leaves me only 1k of headroom, which is indeed very little. I've ordered some 328p's as well just to simplify stuff and not optimize prematurely.

The 328P is a nice chip, and one for which you probably have the most support in terms of libraries and knowledge in this forum.

RobvdVeer:
Great info, this what i was looking for. I thought they were actually calculated at compile time.

Not variables. eg.

for (int i = 0; i < 14; i++)
  pinMode (i, OUTPUT);

It can’t do that at compile time. Especially as some of those pins are on different hardware ports.

From a computer science perspective, Microsoft pretty much proved over the years that "if you have the computer headroom (storage/ram/hard disk, whatever)" they can make your life easier by giving you some honking big libraries. When Rapid Application Development and ease of use are top priority, code size becomes the victim.