Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

debugging - How can I visualise the memory (SRAM) usage of an AVR program?

I have encountered a problem in a C program running on an AVR microcontroller (ATMega328P). I believe it is due to a stack/heap collision but I'd like to be able to confirm this.

Is there any way I can visualise SRAM usage by the stack and the heap?

Note: the program is compiled with avr-gcc and uses avr-libc.

Update: The actual problem I am having is that the malloc implementation is failing (returning NULL). All mallocing happens on startup and all freeing happens at the end of the application (which in practice is never since the main part of the application is in an infinite loop). So I'm sure fragmentation is not the issue.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can check RAM static usage using avr-size utility, as decribed in
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=62968,
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=82536,
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=95638,
and http://letsmakerobots.com/node/27115

avr-size -C -x Filename.elf

(avr-size documentation: http://ccrma.stanford.edu/planetccrma/man/man1/avr-size.1.html )

Follows an example of how to set this on an IDE: On Code::Blocks, Project -> Build options -> Pre/post build steps -> Post-build steps, include:

avr-size -C $(TARGET_OUTPUT_FILE) or
avr-size -C --mcu=atmega328p $(TARGET_OUTPUT_FILE)

Example output at the end of build:

AVR Memory Usage
----------------
Device: atmega16

Program:    7376 bytes (45.0% Full)
(.text + .data + .bootloader)

Data:         81 bytes (7.9% Full)
(.data + .bss + .noinit)

EEPROM:       63 bytes (12.3% Full)
(.eeprom) 

Data is your SRAM usage, and it is only the amount that the compiler knows at compile time. You also need room for things created at runtime (particularly stack usage).

To check stack usage (dynamic RAM), from http://jeelabs.org/2011/05/22/atmega-memory-use/

Here’s a small utility function which determines how much RAM is currently unused:

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

And here’s a sketch using that code:

void setup () {
    Serial.begin(57600);
    Serial.println("
[memCheck]");
    Serial.println(freeRam());
}

The freeRam() function returns how many bytes exists between the end of the heap and the last allocated memory on the stack, so it is effectively how much the stack/heap can grow before they collide.

You could check the return of this function around code you suspect may be causing stack/heap collision.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...