[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] Code Size Causes Crash?
From: |
Kevin Neff |
Subject: |
[avr-gcc-list] Code Size Causes Crash? |
Date: |
Fri, 21 Jan 2005 10:36:17 -0600 (CST) |
I am writing code for the ATMEGA128. After my program reached a certain
size it crashes/resets in the middle of the program. If I increase the size
of the program further, even if that code won't be executed, the MCU
crashed very early in the program and hangs.
I suspect that this problem is related to memory management. It seemed to
me that the problem had something to do with code size, since code that is
not executed causes the problem as readily as code that is executed.
If I understand memory usage correctly, there is ROM/flash (128 kB) that
contains the program and SRAM (4 kB) that is used for variables and stack.
To see how much stack space there is, I subtract the address of _end from
0x1000 (see avr-nm output below). 0x1000 - 0x0229 = a lot. Total program
size is .text + .data, which is ~6.3 kB, and pre-allocated SRAM is ~300 B.
It looks like there is enough space for the stack. I suppose the program
could be taking up more stack space that I extimate, but I doubt that
is the case because the program was fine before adding to the program.
To test if it was a code size issue, I added the following lines.
The variable is already declared and as far as I know, increment and
decrement are not stack intensive processes.
index +=1;
index -=1;
Here is the program sizes
# avr-size main_broken.elf
text data bss dec hex filename
6222 124 173 6519 1977 main.elf
# avr-size main_fixed.elf
text data bss dec hex filename
6222 124 173 6519 1977 main.elf
While investigating this problem, I made a simple program to test code
size. I've incremented and deincremented i many times to increase
code size. with 404 increment and decrement statements, the code is
run correctly (the LED blinks). The addition of one statement beyond
that breaks the program.
It's interesting that the critical size of this program is much smaller than
my application, which did not exhibit code size sensative behavior until it
was 6.5 kB. My test program stopped working at 4.3 kB.
Here is the avr-size output, both the working (smaller) program and the
broken (larger) program.
avr-objcopy --strip-all -O ihex main.elf main.hex
text data bss dec hex filename
4312 0 0 4312 10d8 main.elfa
avr-gcc -mmcu=atmega128 -Wl,-Map=main.map,--cref main.o -o main.elf
avr-objcopy --strip-all -O ihex main.elf main.hex
text data bss dec hex filename
4322 0 0 4322 10e2 main.elf
Here's the difference between the avr-nm outputs.
# diff main_nm_fixed main_nm_broken
56,58c56,58
< 000010d8 A __data_load_end
< 000010d8 A __data_load_start
< 000010d8 T _etext
---
> 000010e2 A __data_load_end
> 000010e2 A __data_load_start
> 000010e2 T _etext
Here is the difference between the map files.
# diff main_fixed.map main_broken.map
4c4
< main_fixed.o (__do_clear_bss)
---
> main_broken.o (__do_clear_bss)
18c18
< LOAD main_fixed.o
---
> LOAD main_broken.o
113c113
< .text 0x00000000 0x10d8
---
> .text 0x00000000 0x10e2
180c180
< .text 0x000000ca 0x100e main_fixed.o
---
> .text 0x000000ca 0x1018 main_broken.o
182c182
< 0x000010d8 . = ALIGN (0x2)
---
> 0x000010e2 . = ALIGN (0x2)
---
> 0x000010e2 . = ALIGN (0x2)
184c184
< 0x000010d8 . = ALIGN (0x2)
---
> 0x000010e2 . = ALIGN (0x2)
195c195
< 0x000010d8 _etext = .
---
> 0x000010e2 _etext = .
197c197
< .data 0x00800100 0x0 load address 0x000010d8
---
> .data 0x00800100 0x0 load address 0x000010e2
210,211c210,211
< 0x000010d8 __data_load_start = LOADADDR
(.data)< 0x000010d8 __data_load_end =
(__data_load_start + SIZEOF (.data))
---
> 0x000010e2 __data_load_start = LOADADDR
(.data)> 0x000010e2 __data_load_end =
(__data_load_start + SIZEOF (.data))
220c220
< .eeprom 0x00810000 0x0 load address 0x000010d8
---
> .eeprom 0x00810000 0x0 load address 0x000010e2
287c287
< OUTPUT(main_fixed.elf elf32-avr)
---
> OUTPUT(main_broken.elf elf32-avr)
299c299
< main_fixed.o
---
> main_broken.o
301c301
< main_fixed.o
---
> main_broken.o
305c305
< main_fixed.o
---
> main_broken.o
342c342
< main main_fixed.o
---
> main main_broken.o
Here is the listing of the test program.
#define __AVR_ATmega128__
#include <avr/io.h>
#include "../../bit_patterns.h" // B0 = 0x01, b0 = ~B0
int main()
{
int i = 0;
int status = 0;
DDRF = B0; // LED on this port
while( 1 )
{
// toggle LED
if( status == 0 )
{
PORTF = B0;
status = 1;
}
else
{
PORTF = 0;
status = 0;
}
i = 0;
i += 1; // 30
i -= 1; // 31
...
i += 1; // 434
// this line must be commented out for the program to run properly
i -= 1; // 435
}
return 1;
}
I don't why my program is sensative to code size. Does anyone have any
ideas about what could cause this problem?
--Kevin Neff