mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega16 - Speicher voll?


Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe gerade festgestellt, dass es mit dem Speicher zusammenhängen 
könnte, dass bei meinem Programm gerade gar nichts mehr ging.

Und zwar wird bei meinem Display, das eigentlich wunderbar 
funktionierte, bei Hinzufügen von simplen Programmcode, der mit dem 
Display selber nichts zu tun hat, nur noch komische Zeichen raus.

Ich benutze AVRStudio und bekomme beim Debuggen folgendes angezeigt:

Program:    7612 bytes (46.5% Full)
(.text + .data + .bootloader)

Data:        764 bytes (74.6% Full)


Die Grenze, bei der Mist rauskommt, liegt bei Data 70 %.

Ich habe mal den Code, bei dem es beim ersten mal auftrat drinnen 
gelassen und dafür anderen ausgeklammert, und dann ging alles.

Ich kann es mir nur erklären, dass der Speicher voll sein muss.
Wieso aber fängt es schon bei 70% an nicht zu funktionieren? Bei 99% 
wäre es ja ok, wieso aber bei 70%?

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Data liegen nicht nur deine Variablen sondern dort
ist (von oben nach unten belegend) der Stack angesiedelt.

Je nach Verschachtelung und Interruptnutzung kommt da
einiges zusammen.

Oft sind (gerade bei Displayanwendungen) Konstanten
(hier Festtexte) als Variablen definiert und belegen
somit Platz im DATA.

avr

Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha okay, na dass hier Variablen liegen wusste ich.
Ich programmiere übrigens mit C, da ich mich mit dem inneren Aufbau 
eines µC (Speicherbelegung usw) nicht so gut auskenne.

Also liege ich wohl richtig in der Annahme, dass der Speicher 
wahrscheinlich voll ist, obwohl 70% im data angezeigt wird?

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also liege ich wohl richtig in der Annahme, dass der Speicher
> wahrscheinlich voll ist, obwohl 70% im data angezeigt wird?

Jein. 'voll' ja (genauer: ab da bemerkst Du den Überlauf), 'obwohl' nein 
(Stack braucht auch Platz, und der ist ebenso wie dynamisch 
angeforderter Speicher (malloc, new, ..) bei den 70% nicht erfasst).

Mögliche Abhilfen: Daten in den Flash auslagern (genauer: nicht 
automatisch in den RAM einlesen lassen sondern nur manuell wenn sei 
benötigt werden), Speicherplatz sparen (Variablengröße, Rekursion, ..), 
oder eine größere Hardware anschaffen.

Für ersteres gibts in der AVR-Libc <avr/pgmspace.h> [1], zweiteres ist 
eine Kunst und dritteres bleibt als letzte Option falls sonst nichts 
hilft.

HTH


[1] 
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen Hems schrieb:
> Aha okay, na dass hier Variablen liegen wusste ich.
> Ich programmiere übrigens mit C, da ich mich mit dem inneren Aufbau
> eines µC (Speicherbelegung usw) nicht so gut auskenne.
>
> Also liege ich wohl richtig in der Annahme, dass der Speicher
> wahrscheinlich voll ist, obwohl 70% im data angezeigt wird?

Ja.
Der springende Punkt ist:
Zur Laufzeit kommt da noch was dazu!

Wenn Funktionen aufgerufen werden, muss irgendwo gespeichert werden, von 
wo sder Aufruf gekommen ist.   -> braucht Platz im SRAM
Wenn Funktionen lokale Variablen erzeugen, müssen die irgendwo hin -> 
braucht Platz im SRAM

und so ist die Anzeige, wieviel Platz da noch übrig ist nur bedingt zu 
geniessen. Je nachdem wie das Programm konkret aussieht und wie es 
abgearbeitet wird, kann da zur Laufzeit noch etwas dazu kommen.

Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok vielen Dank für die Hilfe!


Ich benötige vielleicht sowieso 2 UARTS, da steige ich vielleicht auf 
den ATmega64 um. Aber ich werde es erstmal mit dem Auslagern in den 
Flash probieren.


Danke!

Autor: Karlo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dazu hätt ich noch ne frage:
Was liegt denn alles im heap und was im stack?
Ich mein, lokale variablen sind doch auch demmcompiler bekannt. Wo 
landen die?
Naja ok, bei rekursiven aufrufen dann doch erst zur laufzeit :/
kann man grundsätzlich sagen, globale variablen und variablen der main 
sind bekannt und liegen auf dem heap? Wo kommt das malloc-zeugs hin?
Sind so intressenfragen :)
mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karlo schrieb:
> Dazu hätt ich noch ne frage:
> Was liegt denn alles im heap und was im stack?
> Ich mein, lokale variablen sind doch auch demmcompiler bekannt. Wo
> landen die?

Zuallererst mal:
Ob Heap oder Stack ist einerlei. Alles muss im SRAM erzeugt werden. Das 
ist nun mal der einzige Speicher, der vorhanden ist, auf dem mit 
akzeptabler Geschwindigkeit wahlfrei gelesen und geschrieben werden 
kann.

Der Stack wird benutzt um alles abzudecken, was das Programm zur 
Laufzeit benötigt um im Sinne von C abzulaufen.
Der Heap ist Speicher, aus dem sich dein Programm durch Aufruf 
spezieller Funktionen (malloc, alloc, calloc) bedienen kann.

> kann man grundsätzlich sagen, globale variablen und variablen der main
> sind bekannt und liegen auf dem heap?

Nein.
gloable Variablen werden bei Beginn des Programms im SRAM erzeugt.

Der SRAM ist eigentlich 3-geteilt

   +--------------------------+--------------------+--------------+
   | alles was der Compiler   |                    |              |
   | zur Compiletime schon    |  Heap              |  Stack       |
   | an Speicheranforderungen |                    |              |
   | kennt                    |                    |              |
   +--------------------------+--------------------+--------------+

   |                                                              |
   +-------------------------- S R A M ---------------------------+

Heap und Stack wachsen zur Laufzeit aufeinander zu.
Der Stack von oben nach unten (rechts nach links), der Heap genau anders 
rum.
Alle globalen Variablen sind ja schon zur Compiletime bekannt und werden 
einfach an einem SRAM Ende gesammelt. Effektiv exisitieren sie einfach 
und der Speicher, der dann zur Laufzeit noch zur Verteilung da ist wird 
um diese Anzahl kleiner.
Genau diese Anzahl (also das linke Feld) ist es, die dir AVR-Studio nach 
dem Build als Größe der Data Section angibt.

> Wo kommt das malloc-zeugs hin?

Heap

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen Hems schrieb:
> Ich benötige vielleicht sowieso 2 UARTS, da steige ich vielleicht auf
> den ATmega64 um.

Es gibt auch pinkompatible zum ATmega16 mit 2 UARTs:

ATmega324: 2k SRAM
ATmega644: 4k SRAM
ATmega1284: 16k SRAM


Peter

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Es gibt auch pinkompatible zum ATmega16 mit 2 UARTs:

>ATmega324: 2k SRAM
>ATmega644: 4k SRAM
>ATmega1284: 16k SRAM

Zumindest beim ATMega644 ist Vorsicht geboten:

ATMega644        : 1 UART
ATMEGA644A/P/PA  : 2 UART

MfG Spess

Autor: Jürgen Hems (misteret)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>Es gibt auch pinkompatible zum ATmega16 mit 2 UARTs:
>
>>ATmega324: 2k SRAM
>>ATmega644: 4k SRAM
>>ATmega1284: 16k SRAM
>
> Zumindest beim ATMega644 ist Vorsicht geboten:
>
> ATMega644        : 1 UART
> ATMEGA644A/P/PA  : 2 UART
>
> MfG Spess

Hi!
Ich habe mir gerade hier 
http://atmel.com/dyn/products/param_table.asp?fami... 
mal alle Typen verglichen, und übrig blieb wirklich nur der ATmega644 
:-) Jetzt wollte ich hier fragen, ob man den einfach austauschen kann 
gegen den ATmega16. Aber die Antwort steht ja schon hier.

Mit den zwei UARTs sollte kein Problem sein. Den UART, den ich jetzt 
beim ATmega16 verwende, da muss ich doch eifnach nur eine '0' mit 
hinzufügen.

Für die Initialisierung also anstatt wie bisher:
void init_USART(void)
{
  // Baudrate: 115200 Baud
        // CLK: 14.7456 MHz
  UCSRA = (1<<U2X);
  UCSRB = (1<<TXEN) | (1<<RXEN);
  UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
  UBRRH = 0;
  UBRRL = 15;
}

=>
void init_USART(void)
{
  // Baudrate: 115200 Baud
        // CLK: 14.7456 MHz
  UCSR0A = (1<<U2X0);
  UCSR0B = (1<<TXEN0) | (1<<RXEN0);
  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
  UBRRH0 = 0;
  UBRRL0 = 15;
}
So in etwa müsste man dann generell das UART umändern.
Aber ansonsten kann ich ihn wohl einfach austauschen ja?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.