Where did all my SRAM go? :)

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

I'am using a 2313 and AVR-GCC version 2.95.2 with the -O3 option.

The 2313 has 128Byte SRAM and of course, 32 registers.
I'am using global variables only, to better keep track of my SRAM usage.
There are two 42 byte arrays, and seven single byte variables.
The code consists of main and two interrupt routines (timer overflow and UART_rx). No other function calls.

The problem is, I'am running out of SRAM!

If I'am counting correctly, there should be more than 30 byte SRAM left for the stack if every variable is placed in SRAM, and the only stuff that gets pushed onto the stack is the pc, sr, etc. from the two interrupt calls,
Besides, the compiler should be able to place some variables in registers in order to save even more SRAM, right?

How can I find out exactly how each byte SRAM/register is allocated?

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

I had the impression, that gcc puts all vars in sram and only allocates registers for special purposes (parameter passing, etc.). If that would be true, then you have to reform your calculation :(

Amazing though, that you try C on the 2313, cause I constantly run out of flash on that one in assembler. The 2313 could at LEAST have tripple of todays flash to be really usable.

alex

admin's test signature
 

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

Sorry, I don't know were to find the RAM memory map.

But could it be that you use (constant) strings ? I know the IAR C-compiler puts them standard in flash AND a copy in RAM at startup. This way the RAM is full very soon. This can be put off with a compiler setting in IAR C.

Hope this works

Patrick

admin's test signature
 

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

You may have a look on the .map file.

admin's test signature
 

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

Alexander: Even if GCC only uses registers for special purposes, 30 bytes och SRAM should be enough space for the stack. (only two interrupt calls, nothing more). And yes, I do have quite some problems with flash space too... :) But the application will fit more or less exactly in the 2313's flash mem.

Patrick: Only strings used is two inline asm routines... I doubt the compiler keeps thoose... ;)

Hu: Where can I find that file? The compiler doesn't produce one...

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

AvrGCC uses sram to store your constants.
So, if you are writing something like

"if (a>3) {...}"

the "3" constant will be placed to the SRAM.
GCC thinks it's a fastest way to access constants.

You can read manual about compilier options/switches to disable this feature
(I don't remember now) and for producing ".map" file.

Also you can change the optimization key (in your makefile) to "-os" to get "size optimized" code.

admin's test signature
 

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

Michael: I checked the resulting asm code, gcc does not put contants in SRAM. It uses 'LDI', as it should.
However, I noticed that the compiler promotes pretty much everything to 16bit variables as soon as there is even a remote possibility of a overflow. A simple thing like 0x0116bit promotions? I know that none of my calculations need to be 16bit.

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

The constant "4" gets promoted to 16bit !!!

outp((0x04>>rad),PORTB);

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

C standard forces converting results to int-width. By default, int in AVRGCC is 16bit, but you may change it to 8bit using option -mint8. The options are described in file syntax.txt.

I don't recommend using 8bit int size.

admin's test signature
 

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

AVR is a 8bit CPU, int _should_ actually be 8bits anyway according to C standards.

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

-mint8 took care about all thoose 16bit math instructions.

But there is still way too much stack usage... There are registers enough for both interrupt routines to have their own registers. No need to put the contents of any register on the stack as soon as there is a interrupt.

Is there another AVR compiler that might do better with small amounts of SRAM?