-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Speicherfresser finden

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    26.12.2005
    Ort
    Nürnberg
    Beiträge
    57

    Speicherfresser finden

    Anzeige

    Hallo RoboterNetz-Gemeinde,

    ich bin vor kurzem bei einem Projekt eingestiegen, bei dem wir auf Basis der AT90CAN128 von Atmel entwickeln. Die haben 4kb SRAM. Da das Projekt schon etwas umfangreicher ist und ich nicht den vollen Überblick habe, Suche ich nach einer Möglichkeit herauszufinden, an welchen Stellen im Code viel Arbeitsspeicher statisch belegt wird. Denn schon zur Compile-Zeit ist Data zu 90% voll, da bleibt nicht mehr viel übrig für dynamische Speicherbedarfe.

    Gibt es ein Programm, das einem dabei hilft oder wie macht ihr das?

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ein erster Ansatz ist es mal in das .map File zu sehen. Normalerweise steht da drin welche globale Variable wie viel Speicher braucht.

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Code:
    avr-nm --size-sort -S xxx.elf
    Zeigt die die Größen aller Symbole.
    Disclaimer: none. Sue me.

  4. #4
    Erfahrener Benutzer Begeisterter Techniker Avatar von Jacob2
    Registriert seit
    26.05.2007
    Ort
    Berlin
    Beiträge
    345
    @SprinterSB wo muss man das obige eingeben?
    Habe nämlich ein ähnliches Problem, bei mir ist der Speicher des ATmega8 mit folgendem Code schon zu 47% voll:

    Code:
    #include <avr/io.h>
    #ifndef F_CPU
    /* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
       (z.B. durch Übergabe als Parameter zum Compiler innerhalb 
       des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
       "nachträgliche" Definition hinweist */
    #warning "F_CPU war noch nicht definiert, wird nun mit 1000000 definiert"
    #define F_CPU 1000000     /* Quarz mit 1 Mhz */
    #endif
    #include <util/delay.h>     /* in älteren avr-libc Versionen <avr/delay.h> */ 
    
    #define TEMPO 1800
    #define TEMPO2 2000
    
    int main (void)
    {
      DDRC = 0xFF;
      int ba=0;
      int const _A[] = {0b00001, 0b10110, 0b10110, 0b00001};
      int const _H[] = {0b00000, 0b11011, 0b11011, 0b00000};
      int const _L[] = {0b00000, 0b01111, 0b01111, 0b01111};
      int const _O[] = {0b10001, 0b01110, 0b01110, 0b10001};
      void B (int bb[])
      {
        PORTC = bb[0];
    	_delay_us(TEMPO);
    	PORTC = bb[1];
    	_delay_us(TEMPO);
    	PORTC = bb[2];
    	_delay_us(TEMPO);
    	PORTC = bb[3];
    	_delay_us(TEMPO);
    	PORTC = 0b11111;
    	_delay_us(TEMPO2);
    	ba += 8;
      }
      while(1)
      {
        B(_H);
        B(_A);
    	B(_L);
    	B(_L);
    	B(_O);
        _delay_ms(157 - ba);
    	ba = 0;
      }
      return 0;
    }
    Roboter, CNC Fräse, Elektronik und Basteleien stelle ich auf meiner Website vor...

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.11.2004
    Ort
    Hvalstad, Norwegen
    Beiträge
    140
    @Jacob2:
    Deine Konstanten belegen schon 128 Byte!
    Eine Möglichkeit ist die Variablentypen immer so zu wählen, dass der Wert gerade rein passt, also die kleinst mögliche Variable. Bei 6 Bit wäre das unsigned char, der Speicherbedarf würde um Faktor 4 auf 32 Byte sinken.
    Bei Variablen für Berechnungsergebnisse musst du gucken, dass das größtmögliche Ergebnis auch noch rein passt.

    Oder gleich fest definieren, dann brauchst du dafür überhaupt keinen Speicherplatz.

    Grus
    Lorcan

  6. #6
    Erfahrener Benutzer Begeisterter Techniker Avatar von Jacob2
    Registriert seit
    26.05.2007
    Ort
    Berlin
    Beiträge
    345
    wie fest definieren? mit #define? als int const?

    ich habs doch gefunden, aber mir sagt das nichts was da steht!
    Roboter, CNC Fräse, Elektronik und Basteleien stelle ich auf meiner Website vor...

  7. #7
    Erfahrener Benutzer Begeisterter Techniker Avatar von Jacob2
    Registriert seit
    26.05.2007
    Ort
    Berlin
    Beiträge
    345
    Ich habs jetzt so umgeschrieben:

    Code:
    const unsigned char _A[] = {0b00001, 0b10110, 0b10110, 0b00001};
      const unsigned char _H[] = {0b00000, 0b11011, 0b11011, 0b00000};
      const unsigned char _L[] = {0b00000, 0b01111, 0b01111, 0b01111};
      const unsigned char _O[] = {0b10001, 0b01110, 0b01110, 0b10001};
    allerdings hat mir das höchstens 1% gebracht
    Roboter, CNC Fräse, Elektronik und Basteleien stelle ich auf meiner Website vor...

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Zitat Zitat von Jacob2
    @SprinterSB wo muss man das obige eingeben?
    In einer shell/Konsole/Eingabeaufforderung.

    Du kannst aber auch ein neues Target im Makefile hinzufügen, wenn du lieber mit make arbeitest.
    Disclaimer: none. Sue me.

  9. #9
    Erfahrener Benutzer Begeisterter Techniker Avatar von Jacob2
    Registriert seit
    26.05.2007
    Ort
    Berlin
    Beiträge
    345
    Das Problem ist jetzt, dass ich noch 22 weitere solcher Variablen unterzubringen hätte! Ich hab leider keinen anderen Controller zur Hand
    Der Speicherstand sieht momentan so aus:

    Program: 3830 bytes (46.8% Full)
    (.text + .data + .bootloader)

    Data: 280 bytes (27.3% Full)
    (.data + .bss + .noinit)

    Wie könnte man noch Platz sparen?
    Roboter, CNC Fräse, Elektronik und Basteleien stelle ich auf meiner Website vor...

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    21.07.2008
    Ort
    Moosburg
    Alter
    39
    Beiträge
    49
    Hi!

    Was auch sehr viel Platz braucht, sind Funktionsaufrufe, wenn die Aufruftiefe größer ist. Jeder Funktionsaufruf muss Register und die Rücksprungadresse auf dem Stack sichern.
    Für die nächsten beiden Vorschläge werden mich meine Kollegen der Softwareentwicklung gleich steinigen, weil Code unleserlich wird oder böse Stolperfallen bereits halten kann:
    1. Kleine Funktionen als Präprozessor-Makros schreiben. Ist für Funktionen gut, die z.B. Ports setzen oder auswerten. Ergebnis: Mehr Speicherbedarf durch Code, aber weniger durch Stack.
    2. Funktionen, die nur zum Strukturieren des Codes eingeführt wurden rauswerfen und alles als einen Codeblock schreiben. Ergebnis: Etwas weniger Code, da Aufrufe wegfallen, weniger Stackbedarf. Der Code wird jedoch schwerer lesbar.

    Auf die beiden Methoden greife ich bei meinen Projekten jedoch nur zurück, wenn's wirklich nicht mehr anders geht. Lieber greife ich zu einem größeren Controller.

    Gruß,

    Markus

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •