RAM-Verbrauch

Hallo Gemeinde,

gibt es eine Möglichkeit den RAM-Verbrauch eines Sketches festzustellen.
Wenn ich ein Sketch compiliere bekomme ich ja eine Meldung wie :

Binary sketch size: 7258 bytes (of a 30720 byte maximum)

Aber wie ist es denn um das RAM (2K) bestellt...

Weiss jemand Rat ?

LC_Data

Unter ...\Arduino\hardware\tools\avr\bin findest Du das Programm "avr-size.exe". Wenn Du es mit der .elf Datei (im applet Unterverzeichnis Deines Projektes) als Parameter aufrufst bekommst Du beispielsweise folgende Info:
text data bss dec hex filename
8584 254 717 9555 2553 applet\MotionFreezer_2.cpp.elf

int getFreeMem() {
  int bytes = 0; 
  byte *arr; 
  while ( (arr = (byte*) malloc (bytes * sizeof(byte))) != NULL ) {
      bytes++; 
    free(arr); 
  }
  free(arr); 
  return bytes;
}

Nicht von mir, hab den mal irgendwo gefunden..

Hallo MaFu,

habe ich probiert und klappt auch, aber ist denn dokumentiert was hinter den ausgegebenen Werten steckt ??

Ich habe in meinem File folgende Ausgabe bekommen:
text = 6754 (wäre ich ja theoretisch über den 2 K)
data = 504 (Da wäre ja noch Luft im RAM)
bss = 671 ( Was sagt mir das denn ??)
dec = 7929 (ergibt sich aus Addition von text, data und bss)
hex = 1ef9 (und die Summe noch mal in Hex)

alles in allem dürfte das so nicht laufen da ich im gesamt RAM-Bedarf über dem Möglichen liege oder sehe ich da was falsch (hoffe ich ja)

Oder gilt für eine sicheren Progarmmablauf nur ´data´ und ´bss´ ??

Würde mich über etwas Licht im Dunkel freuen.

@Nachtwind... ist eine nette Option.. die MaFu-Lösung hat den Vorteil das ich es "trocken" schon mal vorchecken kann aber ich werde das mal testweise reinstricken und mal schauen... Danke

LC_Data

text und data zusammen ergeben den Speicherbedarf im Flash (Programmcode).
data und bss zusammen ergeben den Speicherbedarf im RAM (wobei der tatsächliche Bedarf meist ein wenig höher ist).

Danke für die Auskunft.

LC_Data

bss ist der (reservierte) Stack Bereich.

LG Peter

Danke für die Info,

LC_Data

BSS ist der Stack? Das verstehe ich nicht. Jede Variable muss ja erst einmal im Flash landen. Und wird von da aus im RAM initialisiert. Der Stack ist doch für Interrupts zuständig oder bei Funktionsaufruf mit Parameterübergabe oder -rückgabe. Hat da jemand nähere Infos?

Den GCC kenne ich leider nicht so gut.

Michael

Moin Michael

der Stack kommt immer in Verbindung mit Funktionen und Interrupts in's Spiel. Zumindest das Merken der Rücksprungaddresse + evtl. Register

Nein zu den Variablen

void mompel( void )
{
int j;
}

Das int j wird auf dem Stack einfach durch dekremtieren des Stackpointers angelegt.

Tschööö
Peter

Der RAM Verbrauch hängt davon ab was Du so alles treibst. D.h. Unterprogrammaufrufe, malloc() usw. Letztendlich kannst Du das nur zur Laufzeit festestellen und konstant ist das normalerweise auch nicht. Ich nehme dazu folgenden Schnipsel:

void ram_info() {  
  uint8_t *heapptr;
  uint8_t *stackptr;

  stackptr = (uint8_t *)malloc(4);   // use stackptr temporarily
  heapptr = stackptr;                // save value of heap pointer
  free(stackptr);                    // free up the memory again (sets stackptr to 0)
  stackptr =  (uint8_t *)(SP);       // save value of stack pointer

  Serial.print("HP: ");
  Serial.println((int) heapptr, HEX);
  Serial.print("SP: ");
  Serial.println((int) stackptr, HEX);
  Serial.print("Free: ");
  Serial.println((int) stackptr - (int) heapptr, HEX);
  Serial.println("");
}

Ist nicht 100% perfekt, für mich aber bisher immer gut genug.

Nachtrag: und manchmal will man ja auch wissen was denn nun im RAM steht. Das mache ich so:

void hex_dump_n(void* pointer, int n) {    

    if ((int) pointer <  0x10) { Serial.print("0"); }
    if ((int) pointer < 0x100) { Serial.print("0"); }

    Serial.print((int) pointer, HEX);
    Serial.print(": ");
    for (int i = 0; i< n; i++) {                
        Serial.print((*(((uint8_t *) pointer)+i) >> 4) & 0xF, HEX);
        Serial.print(*(((uint8_t *) pointer)+i) & 0xf, HEX);
        Serial.print(' ');
    }

    for (int i = 0; i< n; i++) {            
        if ((*((uint8_t *) pointer+i) >= 0x20) && (*((uint8_t *) pointer+i) <= 0x7F)) {
            Serial.print(*((char *) pointer+i));
        }
        else { 
            Serial.print('.');
        }
    }
    Serial.println(' ');
}

void hex_dump(void* pointer) {    
    hex_dump_n(pointer, 24);   
}

void hex_dump_all() {    

    for (int chunk = 0; chunk < 72; ++chunk) {
        hex_dump_n((uint8_t *)NULL+(32*chunk), 32);
    }
    Serial.println("");
}

Auch nicht super gut aber viel besser als nichts :slight_smile: