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)
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
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.
@ 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
So, ich habe mit DerAlbi jetzt mal rumgesessen. Folgendes ist dabei herausgekommen: Testprogramm:
1 | #include <stdio.h> |
2 | |
3 | int g_Var = 1234; |
4 | |
5 | int main() |
6 | {
|
7 | |
8 | while(1); |
9 | |
10 | |
11 | return 0; |
12 | }
|
Compileraufruf
1 | make -k all |
2 | Building file: ../main.cpp |
3 | Invoking: AVR32/GNU C++ Compiler |
4 | avr32-g++ -O0 -g3 -Wall -c -fmessage-length=0 -mpart=uc3a0512 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp" |
5 | Finished building: ../main.cpp |
6 | |
7 | Building target: cpptest.elf |
8 | Invoking: AVR32/GNU C++ Linker |
9 | avr32-g++ -Wl,-Map,Mapfile.map -mpart=uc3a0512 -o"cpptest.elf" ./main.o |
10 | Finished building target: cpptest.elf |
So. Aufteilung der Speicherbereiche (Extrakt aus dem Mapfile)
1 | Name Origin Length Attributes |
2 | FLASH 0x80000000 0x00080000 axrl !w |
3 | INTRAM 0x00000000 0x00010000 axw !rl |
4 | USERPAGE 0x80800000 0x00000200 |
5 | FACTORYPAGE 0x80800200 0x00000200 |
6 | *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
1 | .data 0x000008d0 0x4 ./main.o |
2 | 0x000008d0 g_Var |
angelegt.
@ 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
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..
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.