Go Down

Topic: Programs bigger than 80k on mega1280 (Read 4442 times) previous topic - next topic

Mark S

Has anyone had success in getting programs to run on the mega that are bigger than 81K.

81648 bytes (of a 126976 byte maximum) works

83244 bytes (of a 126976 byte maximum) does not work

I have tried 2 different bootloaders and have verified that the code is burned ok using avrdude




Does not upload? Or, uploads but does not execute (or execute properly)?

There are multiple kinds of memory. Perhaps you are running out of a different kind, with a sketch that large.

Mark S

Uploads properly, verified with avrdude, does not run. I do not have a debugger to see whats going on.  The extra space is just pgm memory data so its not a bug in the code.


I never suggested it was a bug in the code. There are, however, flash memory limits, SRAM limits, and EEPROM limits. The code goes into SRAM, but some variables and other data goes in flash memory. It is possible that by increasing the data for your application that you have exceeded the flash memory limit, and overwritten some part of the hex code that gets things going.

Mark S

Ok, correct me if Im wrong

Code goes into flash, 128K in the 1280

The 1280 has 8K ram

I am not using any EEPROM

Simply adding 3k more pgm data to the program stops it from working.

Where should I start looking?

I will try to reduce the RAM footprint




Do a search for "Free Memory" on the forum. There are a couple of ways to measure how much memory is available.


The code goes into SRAM, but some variables and other data goes in flash memory.

I think you got this one backwards.  Code goes in flash, variables, stack frames, etc go in SRAM.

progmem uses flash, and is accounted for by the "X bytes used from a Y byte maximum" totals.

My knee-jerk reaction is also that you're running out of SRAM, but it does sound pretty weird.  Do you have any convenient outputs (e.g. serial.print, blinky lights) early in setup()?  Are there lots of global variables, especially global variables that are initialized?


Mark S

OK, I have found something

the code that works has the following
1 - 0000 = 94 0C 7C 0C jmp  00F818 RESET
2 - 0002 = 94 0C 7C 37 jmp  00F86E INT0

the code that does NOT work

1 - 0000 = 0c 94 1c 82 jmp  010438 RESET
2 - 0002 = 0c 94 47 82 jmp  01048E INT0

Notice that the code that does not work jumps across the 64k boundry

Any ideas, or any ideas how to get the linker to put things in a different order.


Mark S

I found the issue in the assembly code. The code generated does not deal with a jump table past 0xffff. For some reason it is loading the BYTE address instead of the WORD address and passing it to a a jump table routine. It does not have the high order bit and then jumps into data space.

I am running avr-gcc version 4.3.3. I have not been able to find v4.5 already compiled for the mac. I found version 4.5 source code and down loaded it but have not been able to get it to compile. (I missing some dependencies)

The issue is when __ctors_end is above 0xFFFF I am not sure what the code is supposed to be doing or why but the value does not have the high order bit. I am using the Arduino environment v0018 which uses gcc-avr.

Below is an exert from the disassembled code

The issue is the lines at 16430 and 16432 they load registers that then get used for an ijmp in the routine I have done extensive comparison between working and non-working code. if this <__ctors_end> label is less that 0x10000 then it works fine.

000163f6 <__ctors_end>:

0001642e <__do_global_ctors>:
1642e: 13 e6 ldi r17 0x63 ; 99
16430: c6 ef ldi r28 0xF6 ; 246
16432: d3 e6 ldi r29 0x63 ; 99
16434: 04 c0 rjmp .+8 ; 0x1643e <.do_global_ctors_start>

00016436 <.do_global_ctors_loop>:
16436: 22 97 sbiw r28 0x02 ; 2
16438: fe 01 movw r30 r28
1643a: 0e 94 5b cf call 0x19eb6 ; 0x19eb6 <__tablejump__>

Mark S

To those that have been reading this topic, I have it figured it out. It has been fixed in gcc 4.4.0

You can see the bug report at

The problem was the fact that the init code (before main) did not handle addresses above 0xffff.

I got a lot of help from folks on avrfreaks getting this figured out.



Sep 08, 2010, 12:45 pm Last Edit: Sep 08, 2010, 12:46 pm by jrraines Reason: 1
Bill Westfield suggested elsewhere that this problem might be circumvented by changing the link script. the linker is called ld. In trying to begin to understand that I was reading some things last night and found a related, but slightly different issue. I looked at
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265576847  as an example of what the makefilelooks like. Here are a couple of excerpts:
Code: [Select]
LDFLAGS = -O$(OPT) -lm -Wl,--gc-sections

I don't understand --gc-sections. Presumably it is the important line since sections is the code that adds offsets to the address being used by the linker.

But this, while not actualy telling the linker what to do, as far as I can tell, is the related problem:
Code: [Select]
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000

The avr Harvard architecture is handled by the linker by putting 800000 as an offset for all of flash memory. But notice that the offset used here, just in a simulator, I think, for eeprom is 810000. Translating to decimal that is 65636 above where the flash memory starts. Thus the debugger/simulator separately assumes flash can't be larger than 65K.

It seems like the Atmel folks, would have a big stake in getting this resolved. How can they hope to sell 2560 chips unless it is???

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131