code compiled on AVR Toolchain is very large

Go To Last Post
30 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I attached two projects, one compiled with AVR Toolchain, and the other with WinAVR 2010.

I had to change the chip from ATmega16 to ATmega32 because when compiled on AVR Toolchain, it is very large.

I added sections for the project in AVR Studio 5 in order to be able to compile. The strange thing is that the AVR Toolchain never complains when the chip flash is smaller than the hex generated...

What can I do about this issue? The hex generated with WinAVR2010 is around 7K, while from AVR Toolchain is larger than 16K. What should I do to obtain the smaller code size?

Attachment(s): 

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

in AVR Studio 5

Note that by default AS5 builds "Debug" not "Release". If you have 5.0 then Debug selects -O0 and Release selects -Os. If you have 5.1 or 6.0 then Debug is -O1 and Release is -Os.

Unless you can think of a good reason not to I'd suggest you make sure both "Debug" and "Release" are set to -Os.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks, u'r absolutely right.

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the code is still a bit much bigger, why is that?

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

is still a bit much bigger

Can you quantify that? Show the avr-size output from both the WinAVR and the AS5 builds. IOW how big is .text in each case. (the size of the .hex file on disk is largely irrelevant as it tells you very little about the actual code size).

Failing that simply run avr-size on the .hex files in each case. See this for example:

E:\avr>dir *.hex
 Volume in drive E is VBOX_windows
 Volume Serial Number is 0000-0805

 Directory of E:\avr

27/04/2011  10:08               279 foo.hex
12/12/2011  18:02                81 asmtest.hex
14/06/2011  15:56               521 prog.hex
14/02/2012  10:08               346 code.hex
17/08/2011  09:13             2,767 plus.hex
03/03/2012  10:52               946 test.hex
29/01/2012  17:50             1,454 foobar.hex
               7 File(s)          6,394 bytes
               0 Dir(s)  238,737,510,400 bytes free

E:\avr>for %a in (*.hex) do avr-size %a

E:\avr>avr-size foo.hex
   text    data     bss     dec     hex filename
      0      94       0      94      5e foo.hex

E:\avr>avr-size asmtest.hex
   text    data     bss     dec     hex filename
      0       6       0       6       6 asmtest.hex

E:\avr>avr-size prog.hex
   text    data     bss     dec     hex filename
      0     176       0     176      b0 prog.hex

E:\avr>avr-size code.hex
   text    data     bss     dec     hex filename
      0     114       0     114      72 code.hex

E:\avr>avr-size plus.hex
   text    data     bss     dec     hex filename
      0     974       0     974     3ce plus.hex

E:\avr>avr-size test.hex
   text    data     bss     dec     hex filename
      0     330       0     330     14a test.hex

E:\avr>avr-size foobar.hex
   text    data     bss     dec     hex filename
      0     512       0     512     200 foobar.hex

As you can see the actual binary sizes are not rally related to the size of the .hex files.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here you go:

>avr-size "...\Code - WinAVR2010\main.hex"
   text    data     bss     dec     hex
      0    8210       0    8210    2012
>avr-size "...\Release\Code.hex"
   text    data     bss     dec     hex 
      0   10752       0   10752    2a00

Actually, I was not referring to hex files sizes, I was talking about this result from AVR Toolchain:

		Device: atmega16
		Program:    9216 bytes (56.2% Full)
		(.text + .data + .bootloader)
		Data:        363 bytes (35.4% Full)
		(.data + .bss + .noinit)

and this result from WinAVR2010:

Size after:
AVR Memory Usage
----------------
Device: atmega16

Program:    6674 bytes (40.7% Full)
(.text + .data + .bootloader)

Data:         99 bytes (9.7% Full)
(.data + .bss + .noinit)

I hope that you understand my point.

Thanks for helping, you guys here are awesome :-]

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you saying both these are built -Os ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Without seeing your actual code, it is difficult to judge!

However both toolsets are easily within the capabilities of your mega16. When you get to 99% flash or 90% SRAM is when you start worrying.

Look at it as a bonus. Atmel provide you with free tools that use more memory. They can sell you bigger chips.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I hope that you understand my point.
There is also a significant difference at the size of Data. Any chance you forgot to link against libm.a in your AVR-Toolchain project?

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW, while the last three answers were being written, I noticed that AVR Studio 5.1.208 is really buggy when it comes to the project settings. For example, if I add a symbol to "ALL configurations" to define F_CPU, I lose settings in both release and debug and they all change to default settings, so I have to configure the memory settings again, change the optimization again, when I go back to add the sections in memory settings, I lose symbols.. Really annoying... Seems for every mouse click I have to save!!?? No, this doesn't also work...

Also, the code generated by the Toolchain doesn't function correctly.

aternst:
Adding this the linker, produced smaller code.

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I specify the following sections in flash:
.MySection1=0x3A00
.MySection2=0x3B00
.MySection3=0x3C00
.MySection4=0x3D00
.MySection5=0x3E00
.MySection6=0x3F00

Why does AVR Studio 5.1.208 defaults to these:
.MySection1=0x7400
.MySection2=0x7600
.MySection3=0x7800
.MySection4=0x7a00
.MySection5=0x7c00
.MySection6=0x7e00

What ever I do, it keeps defaulting to these values, how can I solve this issue?

thanks

Attachment(s): 

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Why does AVR Studio 5.1.208 defaults to these:
Because AVR-Studio tries to be smart. It expects word addresses (as given in the data sheet) and converts them into byte addresses (as needed by the gcc toolchain). That's why the addresses are twice as big.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

That's why the addresses are twice as big.

In case it's not obvious the solution therefore is to start by specifying word addresses (3A00 becomes 1D00, 3B00 becomes 1D80 and so on).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now codes is OK, is this a bug in the studio, or I am missing something in the datasheets, or something I don't understand on how to specify addresses for the studio?

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Now codes is OK, is this a bug in the studio, or I am missing something in the datasheets, or something I don't understand on how to specify addresses for the studio?

The last of those. Atmel designed the AVR, they wrote the datasheets and they wrote AVR Studio. In all of those, when they refer to flash addresses they always use word addressing (each "location" is 16bits wide) on the basis that the smallest divisible amount you can address in flash is a 16it entity (either a one word opcode or two bytes of data).

Meanwhile GCC was written years ago and for many other things besides AVR. As some of its targets are 8bit, some are 16bit, some are 32bit and some are 64bit it chooses to always use 9bit addressing which is common for all architectures (on ARM/Intel addresses generally go up in 4's and on AVR (flash) they go up in 2's).

So there is a brderline issue here between Atmel (16bits) and GCC (8bits). This is why you specify addresses in the Atmel software as 16bit and it then converts it to 8bit (by doubling it) before it passes it to the non-Atmel-designed GCC at the last moment.

Things aren't helped by Atmel trying to pretend in AS5/6 that GCC is "their compiler". It isn't - it's a bolt in from elsewhere and Atmel have to play by GCCs rules just like everyone else who uses it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now under, AVR/GNU C Linker, it looks like this:

-Wl,-Map="$(OutputFileName).map" -Wl,-section-start=.MySection1=0x3a00 -Wl,-section-start=.MySection2=0x3b00 -Wl,-section-start=.MySection3=0x3c00 -Wl,-section-start=.MySection4=0x3d00 -Wl,-section-start=.MySection5=0x3e00 -Wl,-section-start=.MySection6=0x3f00   -mmcu=($DEVICE) ($MEMORY_SETTINGS)

Thank you for the explanation, but why doesn't Atmel allow us to write addresses as they are, why I have to divide by 2 then they double them, this is ironic, this doesn't make any sense, sorry. Things are supposed to be much simpler than what they are doing. No need to double them for me, pass the address as is and that's it. I am wondering how 0x3A00 could be understood in WinAVR days, I did not have to divide it nor double the address, it was passed as is, no changes. So, why don't Atmel follow the same blueprint.

Also, the code generated in WinAVR was smaller, why does it increase with every version up?

Although some will say, sharap, this is a free toolchain, go buy a pro one, but this doesn't justify such issues.

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Thank you for the explanation, but why doesn't Atmel allow us to write addresses as they are, why I have to divide by 2 then they double them, this is ironic, this doesn't make any sense, sorry.


It's because Atmel has ALWAYS used word addresses in their tools and it would confuse existing users if they changed now.

Meanwhile GCC has always used byte addresses for its tools. There's no chance of that ever changing either.

The problem here reall is Atmel trying to pass off GCC as their own compiler. At the very least the dialogs in AS4/5/6 should have a note saying "for use with GCC byte addressing the value you enter here should be half what you intend"

If you used JUST WinAVR then it's true that in your Makefile you would have used --section-start=.name=0x3A00 but if you had previously used AVR Studio 4 as a front end for WinAVR then you would have faced exactly this same issue which has existed for 6 or 7 years. In the AS4 dialog you would create "Falsh" section, call it ".name" and set it to be 0x1D00.

Bottom line: get over it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, as long as I know it now, I should get over it (LOL)

Signature: We need more peripherals in DIP packages. Namely, USB, 12-bit ADC, 16-bit timer, cheaper tool as a programmer/debugger coz STK600 is expensive! Atmel Studio 5/6 sucks! coz it brings MS visual studio crap to AVR world..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the ATMEL's explanation about the memory settings:

Please Refer "Memory Settings->Notes about the AVR port of gcc" Section from the following link

http://www.atmel.no/webdoc/avrtoolchain/avrtoolchain.Projects.GCC_projectOptions.CompilerOptions.html

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That explanation makes no sense! It says:

Quote:
Note that the address has been multiplied by 2 to get the byte address.

How can the reader possibly know that it was multiplied by 2 to get to 0x1FC00 - nothing shows that what was originally entered was 0xFE00 ? If anything that explanation is more confusing than if you had not bothered. Is it so difficult to simply say "if you want use byte addressing to specify memory locations for flash then in Studio dialogs you must half this value and enter it as a word address"?

(but I guess it doesn't actually matter as everyone knows that no one reads manuals until the smoke has been released! Far better would be if the dialog itself had such a note)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I have read this thread because I am experiencing the same with the AVR toolchain with Studio 6.0.1996

I assume that oshaker was specifying the memory sections in the code first and then in the dialog box of the linker..(?)

I don't care about where exactly in the flash the code will be so how do I do it to obtain smaller size?

The program size is approximately double with Studio 6 toolchain as with WinAVR 2010. In Studio 6 I have set Release configuration -Os, garbage collector (-ffunctions-sections -Wl,--gc-sections).

I am working with ATmega644P and I hesitate now and I think that I might go back to WinAVR from 2010

I do not see any benefit from the new toolchain... And the flashing utility is slower than that of Studio 4.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No way does Toolchain generate double size code. In fact I've found it to be a few percent less.

Could it be that you use float and haven't linked with libm.a? That can add about 2K so if your code is only 2K to start I guess this could look like double.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Another possibility is delay routines with variable arguments. That might double the code size if it was pretty small to start with.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok sorry, it seems that I reported messed up results. Thanks for the comments: no I do not use float (clawson) but I use power-save and idle routines with variable arguments (Jim)

So after uninstalling and reinstalling the AVR studios and the toolchains multiple times I have come to the following reproducible results:
AVR Studio v4.18_684 with WinAVR-20100110 now produces
Program: 25810 Data: 1447 using -Os
AVR Studio v6.0.1996 with the latest Toolchain 3.4.1_830
Program: 15494 Data: 1407 using -Os and the garbage collection that I mentioned in the previous post

The funny thing is that before all this reinstalling the Studio4 with WinAVR was compiling about the same size as Studio6 is doing now (I have the hex files). And I can not reproduce this now. :shock:

If I disable garbage collection in Studio6 then the size goes to:
Program: 25418 Data: 1447

I have tested the firmware and it works fine for both builds which leads me to think that the difference is in the dead code. I often do leave the functions in code even though they are never called and I rely on the linker for not including them in the hex and it worked like a charm so far (Studio4 and WinAVR out of the box only with -Os).

But now I do not understand why the WinAVR does not do that with the fresh install. I use it the same way as before. (btw- the -ffunctions-sections doesn't work with WinAVR2010)

The speed of flashing is slower for studio6 however. On ATmega644PV using Program code of about 25k i.e. about 73kB hex file - Studio4 (JTAG ICE mkII firmware 6.6) flashes in about 4.6 seconds and Studio6 (JTAG ICE mkII fimware 7.1d) in about 5.9 seconds.

I stay with Studio 6 and the new toolchain for now, and appreciate any further thoughts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You only get the garbage collection if you ask for it, that is compile with -ffunction-sections and link with -gc-sections.

(NB I'm a bit drunk so you'd better check those options!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are awesome. The mistake was that I was trying -ffunctions-sections instead of -ffunction-sections (without the s in ffunctions) :oops:

So with Studio4.18_684 and WinAVR 2010 AND the grabage collection I now get a functioning code with
Program: 14950 Data: 1151

It is the most compact build from all of the above, and I am back to Studio 4 - it is lighter on the PC than Studio 6 and I anyway use another IDE for writing code.

It remains a mistery how I compiled in the last 4 and a half years without ever manually inserting the garbage collection arguments for the compiler and linker. :roll:

I don't understand why a newer version of the toolchain should produce larger hex for exactly the same code. Isn't that downgrading instead of upgrading? Newer compilers should produce the same or smaller code size otherwise there is no point in having them ... or am I missing something?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I don't understand why a newer version of the toolchain should produce larger hex for exactly the same code.

Because some of the bugs are fixed ;-) (also some changes are not AVR specific and can have a detrimental affect to AVR).

BTW pretty amazing I managed to spell that option correct above as I had had rather a large amount of Sauvignon Blanc at the time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
BTW pretty amazing I managed to spell that option correct above as I had had rather a large amount of Sauvignon Blanc at the time.

STATIC_ASSERT(Sauvignon_Blanc != Vodka);

:-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually it's OK,. I had half a bottle of Sauvignon and then a Vodka+Russian(*) mixer.

(*) http://www.schweppeseuro.com/eu-...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are Man! :)