I recently rebuilt my bootloaders and example code with GCC 4.x so that I could support some newer devices. I found a couple of incompatible differences between the two versions of the compilers that I thought would be useful to document. I call them incompatible because neither works in the "other" compiler.
Initializing the Stack Pointer
Typically with a bootloader you run without all of the C initialization code by using the linker option
Instead you need to either provide your own .init2 section or add initialization to the beginning of main. I do the latter because my bootloader also has a jumptable which jumps to main. The code for GCC 3.x is
/* GCC depends on register r1 set to 0 */ asm volatile ( "clr __zero_reg__" ); /* set stack to end of RAM */ asm volatile ( ".set __stack, @0" :: "i" (RAMEND) ); SREG = 0;
and for 4.x this changes to
asm volatile ( "clr __zero_reg__" ); SP=RAMEND; SREG = 0;
Overriding the Stack Pointer
If you intend to use the standard C initialization code (as is done for most applications) then it is possible to move the stack pointer from its default position of the top of RAM. For example if you are using extended RAM you may want to have a contiguous memory area that is not broken up by a stack. Assuming SP should be at 0x2FF, then the compiler flag for GCC 3.x is
and for GCC 4.x the compiler flag is replaced by the following linker flag
Note that when you move the stack, you need to be even more careful that the stack does not overwrite required RAM as it grows downwards.
Please comment on the above especially if you think there is an easier way to do it or in fact there is a method that is compatible with both versions of GCC.
BTW Because AVRFreaks is having a problem with % symbols in appends, the @0 in the code above should be replaced by % 0 (no space).