A HEX file is an ASCII text file with a great deal of overhead. First, each byte of object code is given as two ASCII HEX digits. Then every 16 bytes, there is a length field, a record type, and an address, also given as ASCII HEX digits. Each line ends with a two byte ASCII HEX checksum. So, of every 16 byes of object code, the HEX file will contain at least about 28 characters. Then there are start and end records, line ends, etc. Overall, a HEX file will typically be about 3X the actual object code size, which is about what you've seen.
:10 0000 00 0C 94 B6 02 0C 94 DE 02 0C 94 DE 02 0C 94 DE 02 18
: => Record start
10 => Data length (16 bytes for most records)
0000 => Start Address
00 => Record Type (00 =Data Record)
0C 94 B6 02 0C 94 DE 02 0C 94 DE 02 0C 94 DE 02 => Data
18 => Checksum
99% of the records in the file will look exactly like that, with different address and data values
A few records (at the start and end of program "sections") will have shorter data lengths
There is a final record which is shorter - 10 characters. There will also be occasional extended address records, which are also shorter.
So, you can approximate the actual code size, but can't know it exactly without parsing the entire file. As an approximation:
16 bytes of binary data plus CR/LF ==> 44 bytes per line
So, multiply the file size by 16, then divide by 44 and you'll be close.
"avr-size *.elf" is the utility used to get the actual size of the avr image. You can probably add it to your makefile or build procedure. The arduino IDE does a bit of massaging of the output to create it's "report" - the raw output looks like:
avr-size *.elf
text data bss dec hex filename
1120 0 9 1129 469 Blink.cpp.elf
52498 16 689 53203 cfd3 chaucer32k.cpp.elf
arduinodlb:
It is what gets sent to the uC. But the uC reads it and turns it into binary stored at particular addresses. It contains information like what address space to put the different sections in, and is an ASCII file, so the hex digits have to be combined to form the final binary.
Actually, no. The downloader (avrdude, or whatever) reads and parses the HEX file, and send binary data to the bootloader, also with periodic, but different, address records. Exactly what gets sent to the Arduino also depends on exactly what you're using to program it, be it a serial cable, ICSP, etc.