Why does an Arduino sketch take up so much precious code space? A few lines of code takes up 2k?
Also, can I create a MAP file somehow (to answer the above question?)?
Why does an Arduino sketch take up so much precious code space? A few lines of code takes up 2k?
Also, can I create a MAP file somehow (to answer the above question?)?
Libraries, my friend, libraries...
Remember those "include"s?
can I create a MAP file somehow
see this thread for info on avr-objdump:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207951658
you can find info on the arguments for avr-objdump here: avr-objdump
I have no "includes". The code is really only a few lines with an interrupt.
I'm not a developer, just a newbie programmer curious why the code is so big.
Is there some way to "turn off" or not include unnecessary stuff?
A sketch with nothing but empty setup and loop functions uses just under 1k of program memory. These are for some of the core arduino functions like the interrupt handlers that will be used when you start using millis and analog writes.
If want to use Arduino functions then you do need to have that code. But I think you may be pleasently surprised how much stuff you can do within the available program memory.
Have fun!
Thanks for the info.
A fellow programmer here at work claims there must be a way to get a MAP file of the code. Is that possible?
000002fc 00000054 T delay
00000400 00000096 T digitalWrite
0000008b 00000014 T digital_pin_to_bit_mask_PGM
00000077 00000014 T digital_pin_to_port_PGM
0000009f 00000014 T digital_pin_to_timer_PGM
0000057a W exit
00000350 00000074 T init
0080010a 00000004 b intFunc
00800100 00000002 D ledPin
0000010a 0000002e T loop
00000144 0000000e T main
000003c4 0000003c T pinMode
00000072 00000005 T port_to_input_PGM
00000068 00000005 T port_to_mode_PGM
0000006d 00000005 T port_to_output_PGM
0080011e 00000080 B rx_buffer
0080011a 00000002 B rx_buffer_head
0080011c 00000002 B rx_buffer_tail
00000496 00000010 T serialWrite
00000138 0000000c T setup
00800112 00000004 B timer0_clock_cycles
00800116 00000004 B timer0_millis
0080010e 00000004 B timer0_overflow_count
text data bss dec hex filename
1090 2 4 1096 448 Blink.elf [arduino-0011]
1122 2 8 1132 46c Blink.elf [arduino-0012]
1218 8 148 1374 55e Blink.elf [arduino-0013]
1406 8 150 1564 61c Blink.elf [arduino-0014]
952 2 12 966 3c6 Blink.elf [arduino-0014 with patch]
An empty sketch is down to about 500 bytes with 14+patch. Note that the size is also dependent on compiler version; there was a significant jump in the size of code produced going between ardunio 11 and 12 with no obvious cause. The gains in patched 14 are due to being able to leave code out, not due to smaller code
The compiler writers (NOT the arduino team) can change their minds at any moment, resulting in significant changes in behavior; compiler writers do that ![]()
y = mx + b
codesize = ( compilerefficiency * sourcesize ) + overhead
That means, when you double the size of your sketch, the amount of memory consumed in the AVR does NOT double. It's not like a basic stamp where nearly ALL of the overhead is "hidden" where you can't see it.
I noticed that (did not do further research though) code is generated even for functions that are not referenced.
So, if one has defined a function, even if that function is not called, the program size grows.
Okay, so I'm not understanding something, then. No surprise.
The code size does affect how long it takes to loop(), doesn't it? So at least in some cases it is relevant?
I doubt that the overall code size affects the time spent in the loop. The code for a function is there, for one to call. But if you don't call it, then no time is spent on that function.
You can measure the time spent in the loop by using millis().
As was said above, code in a sketch that is not used has no impact on execution speed. Code can be executed from an interrupt, but the only interrupt that is operating in a minimal sketch is a few lines of code used for millis and delay. These functions are the heartbeat of almost every sketch so there's not much point in removing them.
So as an experiment, I tool the "Blink" example and exactly doubled the size of the sketch by adding "ledPin2" that gets the same things done to it as ledPin. This cause the sketch (compiled with the arduino environment on Mac) to increase in size from 1414 bytes to 1470 bytes (56 bytes)
(With the patched 14, it when from 954 to 1010 bytes; same increase!)
(with version 11, which has a compiler that is "well known" to produce smaller code, the change was from 1092 to 1148; same increase, so this is apparently not the sort of code whose size changed!)
So following the dubious line of reasoning that one can deduce anything of value by looking at the size of a few lines of code, one might conclude that if adding 7 lines of code (to blink a second LED) adds 56 bytes, then assuming each additional line of similar code added on average ten bytes, Arduino with a 328 chip can have a sketch that is over 3000 lines long ![]()
the interestering question is just: Do additional lines or functions that are not needed correlate with the amount of space used by the binary program?
i have asked myself that question a few times myself when i was reading through libraries. The main question for me was if libs are always compiled the way they are or if the code compiler mechanism leaves out unused functions and variables. Stupid me i never tested it though...
Ok tested it.. there is no difference between programs using libraries with unused functions...
Try it with version 0014.
the blink example referred to above is no bigger if importing but not using the LiquidCrystal library.
Adding the constructor brings in 400 bytes of library code.
Adding a println statement adds 54 bytes but adding a second println only adds another 16 bytes. I think that shows that there is a difference in code size with unused functions.
it's not the number of lines that correlate to code size, its the actual number of bytes of machine code that the compiler produces for each function.
yes.. so its not a big surprise with your numbers. I was just wondering if a library is always compiled and included completely or not - and it seems it isnt ;0)
So, MEM, a program with 3000 lines of code will loop() just a fast as Blink?
Getting back to the beginning tho, is there some way to get a MAP file during the compile process? That would help answer these questions.
The utilities mentioned in reply#2 or reply#6 should give you what you are looking for.
mem, thanks for the help and patience, but I have almost no idea how to use the utilities suggested in reply #2, or how to get any useful information out of the code in reply #6.
Remember that I have a total of about 10 hours of experience writing code of any type, so I'm not really understanding most of what you all are saying.
I was just curious how Loop() might be affected by how long a program is, in case I or someone wanted/needed it to loop at a known or controllable frequency.
So, I asked a co-worker to look at Blink and he was quite surprised that it took up much more than a few bytes of program space. Someone else then jumped in and said "make it print out a MAP file, that will have all the information you want". Hence the question that started this surprisingly long forum topic.
I await yet another attempt by some patient person to explain this in yet another way that my simple mind might understand it.
Thanks in advance!
OK well...
Your question about 3000 lines of code is kind of undefined.. if each of the 3000 lines just did something really simple, like adding 1 to a number, it would definately finish in time. On the other hand, you could come up with some really crazy code that would take more than a second to execute, but it'd be really complex stuff.
As an example of what you can do in a small amount of time, you can read a position from a GPS unit, log the data to an SD card, and display your position on an LCD screen in well under 1/10th of a second.
In general, the arduino is way fast enough for anything you will do. It runs at 16MHz - that's 16 million instructions per second. That's a LOT of changing output pins, reading input pins etc. Of course there is some overhead with the arduino code, but that is the trade-off between SIMPLICITY and EFFICIENCY.
In regards to your desire to do something at regular intervals, this is a well-used feature. The arduino has a functions built in to do this. They are called interrupts. Definately do some reading of the arduino website and this forum, but bassically when the condition for an interrupt is met; can be a change of pin value like a button being pushed, or like you want to do a defined time period has elapsed, the arduino stops whatever it was doing (i.e. it interrupts) and runs the code you want to run when the condition is met.
People use this extensively in timing sensitive applications, like clocks. An interrupt is set to occur every second. when the interrupt starts, it adds one second to the time.