avr-gcc-list
[Top][All Lists]
Advanced

[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







reply via email to

[Prev in Thread] Current Thread [Next in Thread]