How to find out what is to big (for both data and program)

Hi
I have been fighting the 32K program space of my yun for a while now. I already removed the bootloader (so I do have 32K :smiley: ) but I just compiled my program and got the following info (Arduino eclipse IDE)

"/home/jan/programs/arduino-1.5.5/hardware/tools/avr/bin/avr-size" --format=avr --mcu=atmega32u4 "/home/jan/workspaces/arduino/Robot/batterijlader/Release/batterijlader.elf"
AVR Memory Usage

Device: atmega32u4

Program: 33190 bytes (101.3% Full)
(.text + .data + .bootloader)

Data: 2774 bytes (108.4% Full)
(.data + .bss + .noinit)

The arduino IDE would say something like this

"/home/jan/programs/arduino-1.5.5/hardware/tools/avr/bin/avr-size" -A "/home/jan/workspaces/arduino/Robot/batterijlader/Release/batterijlader.elf"
/home/jan/workspaces/arduino/Robot/batterijlader/Release/batterijlader.elf :
section size addr
.data 1024 8388864
.text 32166 0
.bss 1750 8389888
.stab 117348 0
.stabstr 186587 0
Total 338875

So I did come to the conclusion: "this is to big"; all on my own (tab on the back "good boy")
I already got String out of my sketch (that did make a difference)
But now I'm stuck. I probably have some big char arrays and some bad code eating program space; but how can I find the big parts (no need to waist time on a 1 byte peace of code, is there?) in these 33K of compiled program?
I've done some googling but I only found speed profiling things (apart from MAP files and -size command of which I'm not sure how relevant they are).

Any help is appreciated.
Best regards
Jantje

Arrays can gobble up space very easily. How are your char arrays declared ?

You should look at a disassembly of your code.
That will show you everything.
avr-objdump is the command you are looking for.
You run that on your .elf file and it will spit out everything.
I'd recommend using -h and -S options that way you can see everything
and the source code will be embedded.
You can do a man on it to see the other options.

So just cd down into your tmp directory (you can see where that is by
looking at the command line used by the IDE) then run:

avr-objdump -h -S XXX.elf > dump.txt

Then you can edit the dump.txt file and look at everything.
You will see the addresses on the left and can look around to see
what is using up all the space.

--- bill

bperrybap:
avr-objdump -h -S XXX.elf > dump.txt

bill
That really got me going.
I'm not claiming I understand anything I see but my program did go below 100% already. Now the data.
Thank you very much.
Best regards
Jantje

Do you have enough tabled data that it would be worth adding an external EEPROM or flash chip or module? That may require SPI bus and that uses a buffer in SRAM. The default buffer is usually 512 bytes but can be cut.
It's going to take some code and RAM to save a lot more flash. If you don't have enough constants and tables to make it worth it then it's no use.

Think about moving up to a 1284P like Crossroads sells boards for and Nick Gammon shows how to breadboard. Have you the link?

That AVR costs about US$7 so like 3Eu? You get onboard 128K flash, 16K SRAM, 36 I/O pins, 2 Serial ports that can also run as full speed master mode SPI ports in addition to the full mode SPI port, that's serious bang for the buck your project might not outgrow soon. It's a good excuse to buy new toys.

I think your programs abuot 10 times the size it should be! Have you been copying and pasting code take a look at functions an inparticular functions with parameters.

Post 500 or so lines so we can take a look. You could also just attach the code.

Mark

holmes4:
I think your programs abuot 10 times the size it should be! Have you been copying and pasting code take a look at functions an inparticular functions with parameters.

I'm not sure on which information you base that statement.
Lets see I'm using a yun (32K) and the bridge lib and serial and servo and software serial and gps and wire and support a full serial interface to be able to steer my arduino program via a web browser.
As you state my program is 10 times to big you state this all should fit in 3k? I guess not. :grin:

But I am aware there must be improvements. After all I started the thread to be able to find the "sweet spots".
Especially for the lib that does the serial communication there must be improvements. If you want to take a look at the code please do. There are actually 3 libraries and they are available at:

SerialStringReader is a library that allows to read line by line from the serial input.
SerialDataInterface is a base library you need to derive from if you want to share data
SerialCommunicator combines the 2 above for communication to allow to set and get values.
I really welcome feedback.
Och yes the version on github is not the very latest. I already shortened lots of the messages.

GoForSmoke:
That AVR costs about US$7 so like 3Eu? You get onboard 128K flash, 16K SRAM, 36 I/O pins, 2 Serial ports that can also run as full speed master mode SPI ports in addition to the full mode SPI port, that's serious bang for the buck your project might not outgrow soon. It's a good excuse to buy new toys.

You are right but .....
I have plenty of arduino's lying around but here I moved from a mega to a yun because of the linux arduino integration.
The capablity to run linux commands directly from arduino is something I really need because I have 2 robots and a storage server talking to each other via HTTP.
If the mega yun comes out I'll buy a couple right away.

Best regards
Jantje

Quote from: holmes4 on Today at 02:27:43 am
I think your programs abuot 10 times the size it should be! Have you been copying and pasting code take a look at functions an inparticular functions with parameters.
I'm not sure on which information you base that statement.
Lets see I'm using a yun (32K) and the bridge lib and serial and servo and software serial and gps and wire and support a full serial interface to be able to steer my arduino program via a web browser.
As you state my program is 10 times to big you state this all should fit in 3k? I guess not. smiley-mr-green

I'm not sure on which information you base that statement.

40 years of programming experience.

Lets see I'm using a yun (32K) and the bridge lib and serial and servo and software serial and gps and wire and support a full serial interface to be able to steer my arduino program via a web browser.

2k or so NOT any where near 32k and I do use them. By the way with a yun what the hell are you doing with web browser code on the avr.

POST SOME OR ATTACH ALL YOUR CODE OR STOP WASTING OUR TIME!

Mark

You can view the static SRAM usage too using avr-nm. Not overly relevant to code size, but all the initialization data is in flash too.
I use avr-nm.exe -n -S on the elf.

@pYro_65
thanks for the input.

@all
It seems to me I need more understanding of how the code impacts the size of program memory and data memory.
Anyone knows a good reference that can explain me what .text, .data, .bootloader, .bss, .noinit are and how they relate to the code?

Im pretty sure I need to look in my library I posted on github because when I replace the library with a empty replacement I have enough space left.
With the library (SerialCommunicator/SerialCommunicator.h)

Program:   32626 bytes (99.6% Full)
(.text + .data + .bootloader)

Data:       2836 bytes (110.8% Full)
(.data + .bss + .noinit)

with the empty library (SerialCommunicator/FakeComunicator.h)

Program:   24850 bytes (75.8% Full)
(.text + .data + .bootloader)

Data:       2144 bytes (83.8% Full)
(.data + .bss + .noinit)

For the sake of argument I update the code on github with what I currently have on my system.
the libs can be found here

The libraries being used in this project are
I2CLiquidCrystal
SerialCommunicator
SerialDataInterface
SerialStringReader

Best regards
Jantje

I found a good reference.... the AVR data sheet. More specific the AVR CPU core chapter and the AVR ATMega61U4/ATmega32U4 Memories section.
Now I understand the relation between memory allocation and source code I've been able to drop below the 32K again :slight_smile:

Program:   32356 bytes (98.7% Full)
(.text + .data + .bootloader)

Data:       2467 bytes (96.4% Full)
(.data + .bss + .noinit)

Thanks for all the input.
Jantje

PS I finally understand why PROGMEM is a good thing. For those who don't I'll explain
When having a standard char="blabla" he is in the .data section and .data is counted in both Program and Data.
If you use charPROGMEM="blabla" the load will move from .data to .text. This makes no difference for program but it does decrease the Data size.

Much of the complication is because of the Harvard Architecture that the AVR uses.
C only understands a single address space, but the AVR has multiple.
When you have initialized data, obviously the flash must be used to hold those initialized values.
But then in order access it directly, as C requires, it must be in a location that the processor can access directly,
The flash on the AVR is not directly accessible. To account for this, the compiler tools play
some games with the linker and startup code.
They allocate a matching space in RAM, which is directly accessible, for the initialized data
and then also relocate the final location of the initialized data variables to RAM.
Then the runtime startup code copies the initialized data to its new home in RAM.
The PROGMEM stuff is AVR proprietary, and is used to disable the RAM allocation and runtime copy.
This saves RAM, but then in order to access the data you have to use access routines
vs access your data directly.

Other processors don't have this complication.
For example, the ARM and pic32 based processors can access code space directly so with
those processors, you can simply declare you data as "const" and it all works and behaves
as expected, without all the progmem complications.

So for example, if you were to use a DUE, teensy3, chipkit, maple, etc.. You wouldn't have to deal
with progmem and could just use initialized data and const as normal and the const data would
automatically live in flash and you could access it directly.

--- bill

If you want to get down to it, the CPU only sees the registers directly and note that AVR has 32 general purpose registers alone. It is register wealthy for a cheap 8 bit machine.

The F() macro causes Serial to print from flash, I don't know how directly but perhaps copied from flash direct to Serial out RAM buffer.

There are AVR commands to write flash that bootloaders use then lock.
There are AVR FORTHs that write to flash as part of the language, FORTH extends.

We can read flash right into RAM using PROGMEM that also stops automatic flash data copy to RAM at startup.