www.mikrocontroller.net

Forum: Compiler & IDEs Speicheradresse von globalen Variabeln ändern


Autor: Albi G. (deralbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo...
Ich hab nen Problem mit meinem AVR32. Ich hab eine recht große 
Speicherauslastung (großer Stack).
Nun ist es mitlerweile so, dass sich mein Heap (gloabele Variablen) und 
mein Stack gegenseitig überlappen. Das ist ja kein Zustand, der 
erwünschenswert ist.

Komisch sind bei mir die Adressen der globalen Variabeln. Die liegen 
ungewöhnlich hoch. Ich frage mich warum..?


int Global = 40;

int main(void)
{
  volatile int a = 0;
  volatile int b = 1234;

  a = ((int)&Global);

  a = 0; //Debugbreakpoint

return 0;
}

Global liegt bei Adresse 2244. warum? Der Heap fängt doch schon viiiel 
weiter unten an. (Eigentlich sogar bei  0)
Nun frage ich mich, wie man das ändern kann.

In meinem reellen Fall (nicht nur das Test-Mini-Programm) habe ich 
einige globale Variablen.. die kleinse Adresse, die ich bei ihnen 
gefunden habe liegt bei 6500. Ich muss die in den Speicherbereich 
zwischen  0 und 2000 drücken. Wie geht das?

Kann da jemand helfen?

(b liegt übrigens bei 32760.. also 32kb-8Byte.. passt also! nur der heap 
ist mist)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Albi G. wrote:
> Nun ist es mitlerweile so, dass sich mein Heap (gloabele Variablen) und
> mein Stack gegenseitig überlappen. Das ist ja kein Zustand, der
> erwünschenswert ist.

Nö, das ist sogar verboten.
Globale Variablen müssen immer gültig sein, d.h. Stack macht Schrott 
daraus, wenn er reinläuft.


> Komisch sind bei mir die Adressen der globalen Variabeln. Die liegen
> ungewöhnlich hoch. Ich frage mich warum..?

Wenn die Variablen global sind, ist es doch wurscht, was zuerst kommt.
Ich habs beim WINAVR auch mal erlebt, daß er erst die globalen Variablen 
und dann den Stack von oben her angelegt hat.

Es sei denn, Du benutzt globale Variablen für lokale Verwendung.
Dann bist Du selbst Schuld, wenn der Compiler sie nicht besser aufteilen 
kann.
Globale Variablen können (dürfen) nicht überlagert werden!


Peter

Autor: Albi G. (deralbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jajajaja.. das ist mir doch klar, deswegen frage ich, wie ich das 
verhindern kann. ;-)

Wenn ich auf dem Stack 29kb brauche und der AVR 32kb ram hat, dann 
bleiben mir nur noch 3kb frei. Der Stack macht nix verbotenes.. das ist 
so gewollt.

Scheiße is halt, dass die globalen Variablen so missplatziert sind.
Würden sie bei 0 beginnen würde alles passen. Ich hab das vorher ja 
durchgerechnet.
Ich frag mich was vor der Adresse 6500 gespeichert wird... ob die NewLib 
des AVR32 so viel braucht? :-(/

Vllt weiß jemand noch mehr.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Albi G. (deralbi)

>Scheiße is halt, dass die globalen Variablen so missplatziert sind.

Kann ich mir schwer vorstellen. Dann müsste ja quasi das Linkerscript 
eine fehlerhafte RAM-Aufteilung vornehmen. Schau doch mal das Mapfile 
an, dort sollte das alles drinstehen.

>Ich frag mich was vor der Adresse 6500 gespeichert wird... ob die NewLib
>des AVR32 so viel braucht? :-(/

Maybe?

MFG
Falk

Autor: Simon K. (simon) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, ich habe mit DerAlbi jetzt mal rumgesessen. Folgendes ist dabei 
herausgekommen:

Testprogramm:
#include <stdio.h>

int g_Var = 1234;

int main()
{
  
  while(1);
  
  
  return 0;
}
Compileraufruf
make -k all 
Building file: ../main.cpp
Invoking: AVR32/GNU C++ Compiler
avr32-g++ -O0 -g3 -Wall -c -fmessage-length=0 -mpart=uc3a0512 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
Finished building: ../main.cpp
 
Building target: cpptest.elf
Invoking: AVR32/GNU C++ Linker
avr32-g++ -Wl,-Map,Mapfile.map -mpart=uc3a0512 -o"cpptest.elf"  ./main.o   
Finished building target: cpptest.elf

So. Aufteilung der Speicherbereiche (Extrakt aus dem Mapfile)
Name             Origin             Length             Attributes
FLASH            0x80000000         0x00080000         axrl !w
INTRAM           0x00000000         0x00010000         axw !rl
USERPAGE         0x80800000         0x00000200
FACTORYPAGE      0x80800200         0x00000200
*default*        0x00000000         0xffffffff

Interner RAM ab 0x00000000 und Flash ab 0x80000000. Soweit Ok.

Den Rest des Mapfiles hänge ich an.

Man sieht im Mapfile, dass die komplette Standardbibliothek gelinkt 
wird. Mit allen Modulen und somit allen globalen Variablen und 
sämtlichem Code.

Die Frage nun: Warum ist das so? Das Testprogramm beinhaltet doch keinen 
einzigen Funktionsaufruf.

PS: g_Var wird bei
 .data          0x000008d0        0x4 ./main.o
                0x000008d0                g_Var
angelegt.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Simon K. (simon)

>Man sieht im Mapfile, dass die komplette Standardbibliothek gelinkt
>wird. Mit allen Modulen und somit allen globalen Variablen und
>sämtlichem Code.

Das ist link ;-)

>Die Frage nun: Warum ist das so? Das Testprogramm beinhaltet doch keinen
>einzigen Funktionsaufruf.

Vielleicht gibts da irgendwelche Optionen ala cleanup/optimize, die 
bewirkt, dass nur die WIRKLICH verwendeten Funktionen im Code landen.

MFG
Falk

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist natürlich das naheliegendste. Allerdings haben wir diesbezüglich 
schon rumgesucht. Sowohl bei google, als auch bei den OnlineDocs zu den 
Komanndozeilen-Parameter...

Normalerweisem, so wurde gesagt, müsste das der Linker automatisch 
hinkriegen. Aber irgendwas verhindert das jetzt..

Autor: Albi G. (deralbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mich stören ja auch nichtmal wirklich die Funktionen... man bekommt 
unnütze Funktionen sehr wohl aus dem Binary..  aber es sind bei weiten 
noch viiiel zu viele Funktionen drin.
Hauptproblem ist einfach, das die ganze Bibliothek meinen wertvollen 
Speicher zumüllt, ohne dass dieser wirklich effektiv genutzt wird.

Auch wenn man die Standardbibliothek rausnimmt und die daraus genommenen 
Funktionen (sind ja nur 4 Stück) selbst implementerit, fallen nur 4kb 
ram-speicher weg.
Die Adressen liegen immernoch bei >2000. Lasse ich noch mehr 
bibeliotheken weg, so wird auch auf den Startup-Code verzichtet und dann 
geht gar nix mehr.

Sowas blödes. Es frustriert.

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.