Hallo,
gibt es eigentlich Grenzen für eine maximale Anzahl von globalen
Variablen oder maximale Anzahl von verschachtelten Funktionsaufrufen
beim Programmieren "mit GCC"?
Ich habe bei einem sehr umfangreichen Programm das Problem, dass der
Speicherbereich einer globalen char[50] von einem anderen Programmteil
überschrieben wird. Bei der Suche nach dem Übeltäter bin ich beim
Disassembler im Abschnitt No Source gelandet. Folgende Befehle
überschreiben mir das letzte Byte meiner Variable:
00002293: 018C MOVW R16,R24 Copy register pair
000022B8: 91CF POP R28 Pop register from stack
Wenn ich weitere char-Variablen anlege und diese mit sprintf beschreibe,
so werden weitere Bytes (ca. 10-20 - immer die gleichen) der obigen
globalen Variable überschrieben.
Kann mir jemand Tipps geben, wo der Hund begraben sein könnte?
Grüße
Hans
Denkst du ernsthaft, dass jemand auf deine Frage eine sinnvolle Antwort
geben kann?
Wir wärs z.B. mal mit dem Sourcecode? (Nicht alles, nur das betreffende
Stück.)
>gibt es eigentlich Grenzen für eine maximale Anzahl von globalen>Variablen oder maximale Anzahl von verschachtelten Funktionsaufrufen>beim Programmieren "mit GCC"?
ja dein Flashspeicher
>Ich habe bei einem sehr umfangreichen Programm das Problem, dass der>Speicherbereich einer globalen char[50] von einem anderen Programmteil>überschrieben wird.
Das kann nicht sein, da auf dem AVR eine globale char im Datenspeicher
(SRAM) liegt. Programmteile sind im FLASH Speicher
Wieviel Speicher(SRAM) benutzt du aktuell?
Hallo,
ich benutze den ATMEGA64 mit 4KB SRAM. Nach meinen Berechnungen nutze
ich mit dem Programm bereits 3930 Byte. Könnte darin das Problem liegen?
Hier ein Auszug von avr-size
>avr-size -x -A prog.elf
prog.elf :
section size addr
.data 0x996 0x800100
.text 0x483c 0x0
.bss 0x5c4 0x800a96
.noinit 0x0 0x80105a
.eeprom 0x0 0x810000
.stab 0x36c 0x0
.stabstr 0x84 0x0
.debug_aranges 0xdc 0x0
.debug_pubnames 0x82b 0x0
.debug_info 0x2eb3 0x0
.debug_abbrev 0xd8b 0x0
.debug_line 0x315e 0x0
.debug_str 0xa8f 0x0
Total 0xdcb8
> gibt es eigentlich Grenzen für eine maximale Anzahl von globalen> Variablen oder maximale Anzahl von verschachtelten Funktionsaufrufen> beim Programmieren "mit GCC"?
Vermtlich ja.
> Ich habe bei einem sehr umfangreichen Programm das Problem, dass der
Was heißt "sehr umfangreich"? Wieviele hundert Millionen Codezeilen
sind's denn?
> Speicherbereich einer globalen char[50] von einem anderen Programmteil> überschrieben wird.
Das klingt mir eher danach, daß der Speicher des Zielsystems der
begrenzende Faktor ist, und nicht GCC.
> Kann mir jemand Tipps geben, wo der Hund begraben sein könnte?
Du verbrauchst vermutlich zuviel Stack. In diesem Fall überschreibt er
andere Speicherbereiche.
Hans wrote:
> Nach meinen Berechnungen nutze> ich mit dem Programm bereits 3930 Byte. Könnte darin das Problem liegen?
Ja, natürlich. Dein Stack (der wächst ja beim Verschachteln von
Funktionen ebenfalls, je nachdem, wie viele lokale Variablen die
jeweiligen Funktionen so brauchen) überschreibt die statisch
allozierten Variablen.
Hallo,
danke für die Antworten. Kann man den Stack nur dadurch vergrößern, dass
man lokale Variablen reduziert? Wie kann ich den Code ansonst noch
optimieren?
Grüße Hans
Hans wrote:
> Wie kann ich den Code ansonst noch> optimieren?
Wahrscheinlich zu allererst, indem du dir die Ursachen deiner immensen
statischen RAM-Belegung mal zu Gemüte führst.
Wenn du dich traust, stell den Code mal hier als Angang rein. Dann
findet sich bestimmt was. Wenn dein Ram-Bedarf allerdings wirklich so
groß ist, dann hast du den falschen Prozessor.
Oliver
Hans wrote:
> danke für die Antworten. Kann man den Stack nur dadurch vergrößern, dass> man lokale Variablen reduziert?
Umgekehrt wird ein Schuh draus.
Immer so wenig Variablen wie möglich global halten.
Globale Variablen belegen immer Speicherplatz.
Aber lokale Variablen in verschiedenen Funktionen teilen sich den
Speicherplatz.
Versuche mal PC-Programmiergewohnheiten abzulegen und Speicher nicht
wahllos mit der Schöpfkelle zu verteilen, sondern einfach erstmal
ermitteln, wie groß muß ein Variablenarray wirklich sein (worst case).
Peter
Andererseits kann man den Speicherbedarf eines Programms besser
abschaetzen, wenn man mehr globale/statische Variablen statt Variablen
auf dem Stack verwendet.
>Andererseits kann man den benoetigten Speicherbedarf besser abschaetzen,>wenn man mehr globale/statische Variablen statt Stack verwendet.
Ich denke, das hat er gemacht. Da kommt dann 3930 bytes raus...
Oliver
Wollte nur zu Peters Post anmerken, dass es nicht immer sinnvoll ist so
viel wie moeglich auf den Stack zu legen, weil man u.U. sonst irgendwann
zur Laufzeit Ueberlaeufe bekommt die sich schwer abschaetzen lassen.
Aber wenn der Speicher sonst nicht reicht, dann hat man keine Wahl.
>Ich habe bei einem sehr umfangreichen Programm das Problem, dass der>Speicherbereich einer globalen char[50] von einem anderen Programmteil>überschrieben wird.
...
>Wenn ich weitere char-Variablen anlege und diese mit sprintf beschreibe,>so werden weitere Bytes (ca. 10-20 - immer die gleichen) der obigen>globalen Variable überschrieben.
Das muß schon ein SEHR spezielles Programm sein, welches gleich mehrere
dieser mit sprintf (und damit aus anderen Variablen) erzeugten
char-Felder global, (und nicht konstant), vorhalten muß. Ein einziger
buffer, den man immer abwechselnd beschreibt, und ausgibt, wäre
vielleicht auch eine Möglichkeit.
Flash scheint ja ausreichend vorhanden zu sein, sonst könnte man auch
noch über das sprintf nachdenken.
Oliver
Der Grund für die starke Belegung des statischen RAMs ist ein großes
Menü, eine sehr große structure (ca. 1200 Byte) und andere
char[]-Variablen.
Ich verschiebe gerade den vielen Text, sowie die Konstanten in den
Flash. Dieser ist ja momentan nur zu einem Drittel belegt.
Danke für die Tipps, hab wieder viel dazugelernt ;-)