Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
niemamnogi
PostPosted: Jul 09, 2010 - 02:19 PM
Newbie


Joined: May 12, 2010
Posts: 14


Hello. I have a question about how compiled program code is located in microcontroler, for example lets consider ATmega128 and ATmega32.
ATmega128 wrote:
128 [kB] Flash Program Memory
4 [kB] Internal SRAM
4 [kB] EEPROM
ATmega32 wrote:
32 [kB] Flash Program Memory
2 [kB] Internal SRAM
1 [kB] EEPROM
AVR Studio 4 give information about memory usage of current project in given microcontroler. This is divided into two parts: Program and Data. I have noticed that information about Program covers the Flash Program Memory, and Data the Static RAM. So we can say that program is loaded into Flash and whole program data into SRAM?

Additionally I have noticed as well that when I use global variable for example:
Code:
#define N 200

unsigned char BUFFOR[N];

int main(void)
{
    ...
}
Then AVR Studio inform that those 200 [kB] use place in SRAM (Data memory usage grow up). But when I do something like that:
Code:
#define N 200

void function1(void);

int main(void)
{
    function1();
}

void function1(void)
{
    unsigned char BUFFOR[N];
    ... /*Operations on this buffer*/
}
Then AVR Studio don't show where this buffer was located - Data and Program memory usage remain the same. So where this buffer is located? As well in SRAM? So if I will use many 200 [kB] buffers in functions, there is a possibility that microcontroler will have to less memory (even if AVR Studio informs that everything is correct and should fit)? Or those buffers will be located in Flash memory? That would be more practical because in my humble opinion in ATmega128 the 4 [kB] for Data is too small in comparison to 128 [kB] for Program.

My last question is about such example: let's consider that I have a project on ATmega128 and I want to migrate it to ATmega32. On ATmega128 it looks for example like this:
AVR Studio 4.18 wrote:
AVR Memory Usage
----------------
Device: atmega128

Program: 26626 bytes (20.3% Full)
(.text + .data + .bootloader)

Data: 2758 bytes (67.3% Full)
(.data + .bss + .noinit)
So the Program will fit ATmega32 32 [kB] of space, but problem is with Data because ATmega32 will need approximately 710 [B] of SRAM more. Is such migration possible? Or I will need to reduce the number of global variables to decrease used amount of SRAM?

Than You for any discussion. Those informations are only my theoretical examples, and they does not cover any practical problem (yet).
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 09, 2010 - 03:16 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71119
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Then AVR Studio don't show where this buffer was located - Data and Program memory usage remain the same. So where this buffer is located? As well in SRAM?

It is in SRAM but it's only created when function1() is entered and it's destroyed when the function exits. The place it's actually located is on the stack. As this picture in the manual:

http://www.nongnu.org/avr-libc/user-manual/malloc.html


shows the global variables (.data=initialised, .bss=uninitialised) are placed at the start of SRAM and in your case .data+.bss is using 67.3% of the RAM. The stack where "locals" (also called "automatics" because they are created automatically when functions are entered) is initially set to the very end of SRAM and it works downwards.

You only get problems once the SP gets so low that it starts to impinge on the end of .bss (and eventually might even make it down to .data). In your case the 67.3% means that there are 4096-2758=1338 bytes left for use by the stack (assuming you don't use malloc()/free() to allocate "heap" memory). So a [200] char array should be no problem.

A rule of thumb is that most programs need about 25% for stack usage so as long as your 67.3% doesn't go over 75% you are fine.

However the mega32 only has 2048 bytes of SRAM so your 2758 don't even fit, let alone room for 1358 bytes of stack.

As it stands this program MUST use an AVR with 4K or more SRAM.

Maybe you can re-use some of the ram buffers to reduce usage in .data or .bss or perhaps there's some constant .data being copied out to RAM that could be kept in PROGMEM to reduce SRAM usage?

Cliff

PS this thread is really about GCC - unless it develops into a more general RAM usage question I may move this to the GCC forum.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
niemamnogi
PostPosted: Jul 09, 2010 - 03:44 PM
Newbie


Joined: May 12, 2010
Posts: 14


Thank You very much, Yours informations were very useful for me.

If You say:
clawson wrote:
You only get problems once the SP gets so low that it starts to impinge on the end of .bss (and eventually might even make it down to .data)
What can happen in such situation? Microcontroler can get restarted automatically? Or just program don't work properly?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 09, 2010 - 04:00 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71119
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

What can happen in such situation? Microcontroler can get restarted automatically? Or just program don't work properly?

Almost anything might occur. One way round where the stack is over .bss will be that bytes the CPU writes to the stack will start to appear randomly in some of the variables you defined in .bss. The other way round (possibly worse?) is where inside a routine you write to one of the .bss variables but in doing so you actually corrupt data held on the stack which could be either a stack frame automatic variable, or a PUSH'd copy of one of the AVR registers or, perhaps worst of all, a RETurn address to be used to get back to where a function was CALLed from. If something like that is corrupted then when "RET" is executed the PC will be loaded with some junk value and the CPU will start to execute random code/data in the code flash which is utterly disastorous.

The bottom line is that in your program design you must do a "memory budget" where you determine what the worst case RAM usage will be in your program and if it is such that there's so much in .data and .bss and likely to be so much created on the stack that it hits .bss then you need to find a way to use less RAM or add RAM to the system (perhaps by trading up to a larger AVR).

Obviously when doing a memory budget or scavenging for RAM it makes most sense to see if you can reduce the "big things" first (which basically means arrays and large structs). When you have "char foo[200]" you need to consider whether [100] would have been enough. Or if you have foo[100] and bar[100] you need to consider if you could make a combined foo_bar[100] which is sometimes used for foo[] purposes and at other times bar[] purposes.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits