Arduino 1.0 produces 25% larger binary?

First, most of the increase, 4700 bytes, appears to be due to the Ethernet library.

Second, I wrote the SdFat base library for SD.h but I was not involved with the Arduino group's wrapper for SdFat. The extra 1500 bytes is due to features in the wrapper for SdFat. A very old version of SdFat is used as the base for SD.h so the wrapper takes extra memory.

The current version of SdFat has all the features of SD.h and is smaller by around 1500 bytes. The problem is that the SD.h wrapper implements a different API than SdFat so you can't just use to the new version of SdFat without a lot of program changes.

If you could live with FAT16 on standard SD cards with 2 GB or less, you could use my Fat16 library. It is much smaller than SD.h or SdFat.

A beta of the SdFat and Fat16 libraries that work with Arduino 1.0 is here Google Code Archive - Long-term storage for Google Code Project Hosting..

I will soon post the a non-beta version of both libraries here Google Code Archive - Long-term storage for Google Code Project Hosting. and here Google Code Archive - Long-term storage for Google Code Project Hosting..

most of the increase, 4700 bytes, appears to be due to the Ethernet library.

It looks to me like a big part of this is because 1.0 has a DNS client, which is apparently included in your sketch even though you're not using it. This causes UDP to be included as well. This is at least a couple thousand bytes of code that didn't exist at all in 0022...

BTW, on my system, your sketch compiles to 30682 bytes, which still fits in a 32k AVR...
(I did generate a trivial memoryfree.c from the postings in the forums, rather than digging up an actual library, but other than that I should have the same code...)

I commented out the humidity sensor to get below 31k, but it still didn't upload to the board. So maybe another error I got with 1.0? I'll see if I can fix it, thanks for your help!

It seems the infamous 'round' issue is back again... at least code-size wise. This time in 'Arduino.h'. They have done something to the compile process, so at least I don't get any errors from that anymore. BUT if I comment out the '#define round...' line, the code-size goes down by 190 bytes!

void setup(void) {
}

void loop(void) {
 volatile long a = round(digitalRead(0)); 
}

compiled with '#define round...' in 'Arduino.h': 1412 bytes
compiled without '#define round...' in 'Arduino.h': 1222 bytes

This should affect linux users with avr-libc version 1.7.1 I think. It comes with a internal version of round() and doesn't need the '#define round...' anymore. I think there is a patch for this, but somehow it got ignored for 1.0.

BTW, I did not check if the produced code actually is working. I just removed the define out of old habit and was rewarded with almost 200 bytes less file size.

barish:
I commented out the humidity sensor to get below 31k, but it still didn't upload to the board. So maybe another error I got with 1.0? I'll see if I can fix it, thanks for your help!

If you have code under 31k and you have a m328 based board and it isn't fitting, then it
sounds like you are not using optiboot.

Switching to the optiboot bootloader will get you more space so that images up to 32256 bytes will fit
vs 30720 with the older bootloader.

--- bill

Hi to all,

With a simple test I verified the final size for the web server example for the ethernet library for the 3 compilers.

Arduino IDE Size Compiled
0022 5446
0023 5446
1.0 10146

From this simple test for a specific library the increase of size was almost 50%.

This isn't good but I believe that the Arduino team will address this problems. In the meanwhile I will use the 0023 and 1.0 IDE for my programs.

Regards,
Luis Sismeiro

WebClient grows from 5522 bytes in 0022 to 12456 bytes in 1.0

westfw:
WebClient grows from 5522 bytes in 0022 to 12456 bytes in 1.0

Nice. What was the release date for the ATmega648 again?

Seriously, that kind of bloat will stop me from going to 1.0.

I download 1.0, and copied my 0022 libraries to the library ( TinyGps for example ) but it doesn't run, and I don't have the experience or time to try and modify the library.
However, looking at the notes about 1.0, there was a useful looking library for parsing text and data from character stream, and changing the data type in one go.

Would it be wasting my time to see if this library work in 0022 ?

that kind of bloat

Apparently gets you DHCP, DNS, UDP, and some small functions (random, memcmp, etc) that they use.

More detailed analysis later, perhaps.

westfw:

that kind of bloat

Apparently gets you DHCP, DNS, UDP, and some small functions (random, memcmp, etc) that they use.

That was my understanding. I can potentially use some of those features, but will have to look mighty closely at the cost/benefit ratio. OTOH, if a person doesn't need them, it'd be nice if they weren't just along for the ride, taking up memory.

Boffin1:
However, looking at the notes about 1.0, there was a useful looking library for parsing text and data from character stream, and changing the data type in one go.

Would it be wasting my time to see if this library work in 0022 ?

Maybe you're thinking about the new Stream functions? They're find(), findUntil(), parseInt(), parseFloat(), readBytes(), readBytesUntil()... and you can use with the Serial, Ethernet's Client, and other interfaces that inherit the Stream API. I believe they were original written/contributed Michael Margolis. I submitted a few minor bug fixes while 1.0 was in development.

These are pretty easy to back-port to Arduino 0023. I believe you can just copy Stream.cpp into the core, and then edit Stream.h to add the extra definitions. I did this in Teensyduino's core, so these all work on 0022 and 0023 on Teensy. I haven't tested on Arduino, but if simply copying the .cpp and merging the .h doesn't work, you could always run the Teensyduino installer and look at my code to help resolve any problems.

So I've been poking around. It looks like the most useful existing command is part of the "nm" symbol dumping utility.
In particular, "hardware/tools/avr/bin/avr-nm --demangle --size -r *.elf" will take you right to the "big" functions:

00000370 T SdFile::write(void const*, unsigned int)
000002f6 T __vector_24  (I2C)
000002d4 T DNSClient::ProcessResponse(unsigned int, IPAddress&)
0000029c T changeTemp(char*, char)
0000028a T SdVolume::init(Sd2Card*, unsigned char)
0000024a T SDClass::open(char const*, unsigned char)
0000023a T SDClass::getParentDir(char const*, int*)
0000022a T SdFile::read(void*, unsigned int)
0000021e T SdVolume::allocContiguous(unsigned long, unsigned long*)
0000021c T changeTime(char*, unsigned char, unsigned char, unsigned char)
0000020e T SdFile::open(SdFile*, char const*, unsigned char)
00000200 B SdVolume::cacheBuffer_
000001d2 T webServer()
000001a6 T Sd2Card::init(unsigned char, unsigned char)
00000198 T werteSpeichern()
00000196 T SdFile::truncate(unsigned long)
0000016e T DallasTemperature::calculateTemperature(unsigned char*, unsigned char*)
00000166 T DNSClient::BuildRequest(char const*)
00000154 T malloc
00000152 T SdFile::seekSet(unsigned long)
0000013a T Sd2Card::readData(unsigned long, unsigned int, unsigned int, unsigned char*)
00000138 T SdVolume::fatPut(unsigned long, unsigned long)
0000012c T DNSClient::getHostByName(char const*, IPAddress&)
0000012c T OneWire::search(unsigned char*)
00000126 T getTime(File&, int&, int&)
0000010c T HardwareSerial::begin(unsigned long)
00000100 t dscrc_table
000000f4 T setTimeToND(char*)
000000f0 T EthernetServer::available()
000000ee T EthernetClass::begin(unsigned char*, IPAddress, IPAddress, IPAddress)
000000e8 T EthernetClient::connect(IPAddress, unsigned int)
000000e6 T SdVolume::fatGet(unsigned long, unsigned long*) const
000000e4 T DallasTemperature::begin()
000000e0 T DS1307::get(int, unsigned char)
000000e0 T EthernetClient::connect(char const*, unsigned int)
000000e0 T EthernetUDP::beginPacket(char const*, unsigned int)
000000de T SdVolume::chainSize(unsigned long, unsigned long*) const
000000dc T SdFile::openCachedEntry(unsigned char, unsigned char)
000000d6 T W5100Class::send_data_processing_offset(unsigned char, unsigned int, unsigned char const*, unsigned int)

If there are things we can do so that DHCP and DNS aren't compiled in if they aren't used, that would be great.

are things we can do so that DHCP and DNS aren't compiled in if they aren't used

I could think of ways to do this in C, but the C++ techniques are beyond my expertise. It's obviously possible, since other libraries manage to leave out sub-components that aren't used (ie floating point output from "print".)

This would be a good thing to put in a tutorial...

mellis:
If there are things we can do so that DHCP and DNS aren't compiled in if they aren't used, that would be great.

I thought we were already using the compilation parameters that enabled this? (Putting functions into separate blocks that aren't included by the linker if not used or something like that.)

What might make this a slightly moot point in terms of the example: Shouldn't the basic example use DNS anyway instead of hardcoding an IP address for Google?

--Philip;

Hmm. In fact, the WebClient example does use DHCP for its initial config now.
I can't figure out how DNS is getting pulled in, though. EthernetClient::connect() does call dns, but only in the method that has a string argument, so I thought that would be enough to get it omitted during link...

Could a virtual connect be the culprit...

class EthernetClient : public Client {
public:
...
virtual int connect(IPAddress ip, uint16_t port);
virtual int connect(const char *host, uint16_t port);
...

Maybe, two virtual members only creates an overhead of two pointers in the v-table ( pointers to the derived type ) during run-time.

But sometimes can increase code generation by upto 50 bytes per 'virtual' usage, sometimes even more.

If you have no need to control many different derived interfaces through a unique single interface, scrap the base class.

Arduino should #define it to turn off the client class when not needed.