Forum: Mikrocontroller und Digitale Elektronik Warnt mich der avr-gcc, wenn mein Programm zu viel SRAM benötigt ?


von Giuseppe B. (brungi)


Lesenswert?

Hallo Leute !

Zunächst einmal ein frohes und gesundes neues Jahr an alle hier !

Dann zum Thema:

Ich bastel gerade an einem Projekt mit nem atmega32. Darin kommen auch 
einige char-Arrays vor, welche zur Laufzeit (vermutlich) in dem SRAM 
geladen werden.

Irgendwann habe ich mich gefragt, was wohl passieren wird, wenn mein 
Programm versucht, mehr SRAM des µC s zu belegen, als Dieser überhaupt 
hat.

Merkt das der Compiler ( avr-gcc (GCC) 4.3.3 ) und warnt mich davor ?

von Ingo (Gast)


Lesenswert?

Kommt darauf an, im Normalfall ja.


Ingo

von Giuseppe B. (brungi)


Lesenswert?

Ok , Danke.

Compiler - Warnungen sind natürlich eingeschaltet :)

von Klaus (Gast)


Lesenswert?

Giuseppe B. schrieb:
> Compiler - Warnungen sind natürlich eingeschaltet :)

Das wird in diesem Fall nichts nützen, es ist IMHO der Linker, der das 
merkt.

MfG Klaus

von g457 (Gast)


Lesenswert?

Korrektur: im Normalfall nein [0]. Deswegen entsprechend aufpassen was 
man macht.

[0] avr-size kann höchsten eine ziemlich einfache statische Analyse 
abliefern. für alles andere (und alles andere ist in der Regel das 
problematische, weil eben nicht so ohne weiteres statisch analysierbar) 
brauchts große Geschütze.

von bhj b (Gast)


Lesenswert?


von Falk B. (falk)


Lesenswert?

@  Giuseppe B. (brungi)

>einige char-Arrays vor, welche zur Laufzeit (vermutlich) in dem SRAM
>geladen werden.

Das kann man vermutlich am Sourcecode erkennen,.

>Irgendwann habe ich mich gefragt, was wohl passieren wird, wenn mein
>Programm versucht, mehr SRAM des µC s zu belegen, als Dieser überhaupt
>hat.

Es wird komisch laufen oder abstürzen.

>Merkt das der Compiler ( avr-gcc (GCC) 4.3.3 ) und warnt mich davor ?

Meistens NICHT!. Denn der Compiler/Linker kann nur den statischen 
Speicherverbrauch ermitteln. Also alle globalen Variablen oder statische 
Variablen in Funktionen. Alle NICHT statischen Variablen in Funktionen 
kann er NICHT messen.

1
void ausgabe (*char) {
2
  static uint8_t zaehler;  // statisch
3
  char tmp[10000];   // dynamisch, Absturz
4
}

von Ingo (Gast)


Lesenswert?

Was passiert eigentlich, der man den Index eines Arrays größer als Array 
selbst? Aus Erfahrung weiß ich das das Programm dann durchdreht bzw. 
Nicht weiter abgearbeitet wird. Aber was passiert intern im Speicher?


Ingo

von Falk B. (falk)


Lesenswert?

@  Ingo (Gast)

>Nicht weiter abgearbeitet wird. Aber was passiert intern im Speicher?

Dein Datenzugriff geht daneben!

von Ralph (Gast)


Lesenswert?

Ich betrachte den Compiler hier jetzt mal als ganzes , damit meine ich 
C-code rein bis HexFile zum flashen raus., Inklusive LINKER, 
Postbuildsteps,... und was da sonst noch alles läuft.

Den Speicherbedarf deiner statisch vorhandenen Variablen kennt der 
Compiler.
Also alles was GLOBAL oder VOLATILE mit festen Größen angelegt ist.

Anders sieht es bei lokalen Variablen aus, die in der Regel auf dem 
Stack liegen.

Ebenfalls  sobald du MALLOC , HEAP, ... verwendest, hast du eine 
dynamische Rambelegung.

Diese dynamische Rambelegungm, die ja erst zur Laufzeit aktiv wird, kann 
dein Compiler nicht berechnen.


Das heißt wenn du wissen willst ob dein Variablen Speicher ( GLOBALE und 
VOLATILE) ausreicht folgende Schritte.
1. Im LinkerCommand File den Rambereich für Stack und Varibalen sauber 
trennen durch eigene sections.
2. KEINE dynamische Variablen verwenden. ( Verbot von MALLOC,... )

==> der Compiler kann dir nun eine verlässliche Warnung zum  Variablen 
Rambedarf geben.

ABER ob dein Stack ausreichend groß dimensioniert ist, kann dir kein 
Compiler sagen. Das geht nur zur Laufzeit.
Möglichkeiten zur Erkennung:
Die ersten und letzten Adressen des Stacks mit einem festen Muster 
befüllen
zb 0xAA55AA55.
Dann zyklisch alle x Msec prüfen ob das Muster noch da steht. Wenn das 
Muster nicht mehr dort steht ist dein Stack zu klein.

von Ralph (Gast)


Lesenswert?

Ingo schrieb:
> Was passiert eigentlich, der man den Index eines Arrays größer als Array
> selbst? Aus Erfahrung weiß ich das das Programm dann durchdreht bzw.
> Nicht weiter abgearbeitet wird. Aber was passiert intern im Speicher?

Es gibt mehrere Möglichkeiten.
1. Du liest das was eine andere Variable an ihrem Speicherplatz enthält.
2. Du überscheibst eine andere Variable mit einem für diese Variable 
unsinnigen Wert.
3. Dein ArrayZeiger zeigt auf eine ungültige Addresse, das heiß 
Außerhalb des Rambereiches.

Auswirkungen:
1. Kommt drauf an was deine Funktion mit dem wert macht, von "Es 
passiert nichts" bis Absturz ist alles möglich
2. Wie bei 1. allerdings  kommt es nicht auf die Funktion an die den 
fehlerhaften Zugriff erzeugt, sonder die die betroffene Variable nutzt.
3. Das gibt bei den meisten ( ich wüsste jetzt keine Ausnahme ) µC einen 
nicht maskierbaren Interrupt (NMI) oder einen Reset.

Es gibt da auch keinen Unterschied zwischen einem Variablen Array oder 
dem Stack. Verhalten und Auswirkungen sind die gleichen. Allgemein 
betrachtet ist ja auch der Stack nichts anderes als ein Array.

von Markus M. (adrock)


Lesenswert?

...habe mich übrigens gerade mit sowas in den A... gekniffen.

Ein Programm lief erst ohne Probleme, habe dann ein Array vergrößert bis 
der Linker (oder ist es avr-size? Studio 6 gcc toolchain) ca. 90% des 
Speichers als genutzt ausgegeben hat und mich dann gewundert, dass mein 
Programm plötzlich merkwürdige Effekte zeigte.

Kein Wunder, das Ende des Arrays hat dann Variablen auf dem Stack/Heap 
überschrieben :-(

Da bin ich aber auch erst beim Debuggen drauf gekommen...

Insbesondere wenn man auch Funktionen aus der avr c library nutzt, 
dürfte es mit dem Schätzen im Voraus schwert werden...

Markus

von Reinhard Kern (Gast)


Lesenswert?

Ralph schrieb:
> Diese dynamische Rambelegungm, die ja erst zur Laufzeit aktiv wird, kann
> dein Compiler nicht berechnen.

Aber man kann Stack und Heap daraufhin überwachen, ob sie 
ineinanderlaufen (normalerweise wird ja der Heap von unten und der Stack 
von oben befüllt), dafür gibt es verschiedene Möglichkeiten. Das nützt 
bloss nicht übermässig viel, weil der Fehler ja nicht zu beheben ist, 
man kann höchstens versuchen, noch eine Fehlermeldung irgendwie 
abzusetzen und den Prozessor anhalten, ein sicheres Weitermachen ist 
nicht möglich.

Viele Systeme machen das standardmässig so, i.A. kann man dann einen 
Schalter setzen, ob die Überwachung aktiviert wird - was natürlich 
Rechenzeit kostet.

Gruss Reinhard

PS in ähnlicher Weise kann man auch Strings oder andere Arrays auf 
Überlauf überwachen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.