Hi, wie kann ich bei meinem AVR rausfinden, was genau meinen Data Memory verbraucht? folgendes gibt mir avr-gcc aus (AtmelStudio) Program Memory Usage : 5730 bytes 4,4 % Full Data Memory Usage : 2584 bytes 15,8 % Full Verstehe ich nur nicht ganz, wo die 2.5K herkommen. Was macht er mit solchen Deklarationen im Programmcode? uint8_t data_buffer[4096]; Ich haette erwartet, das er dann auch min. 4K "Data Memory Usage" hat, da er dieh 4K doch reservieren sollte, oder? Anscheinend scheint das aber anders zu laufen - nur dann ist mir nicht klar wie sich die 2.5K zusammensetzen. Aus dem .map File werde ich irgendwie nicht schlau. In dem Abschnitt "Memory Configuration" scheinen wenn ich das richtig sehe, Pro gelinktem Object-File und den jeweiligen Funktionen aus dem File, der jeweilige Bedarf an Data-Memory zu stehen? Ist dem so? .text.wdc_read_data_from_p8k 0x00001028 0x40 wdc_if_pio.o 0x00001028 wdc_read_data_from_p8k soll mir das sagen, das in der Funktion wdc_read_data_from_p8k, 0x40 Byte Daten in de Program Memory geladen werden? Wiso meine 4K nicht mit eingerechnet werden verstehe ich aber irgendwie trotzdem nicht. Wie funktioniert das?
Hallo, 1.) Ist die Variable global oder lokal definiert? 2.) Wird die Variable bereits verwendet? Grüße Manuel.
1. lokal 2. nur als Pointer-Argument zu anderen Funktionen. Die schreiben dann bis zu 4K Daten rein. wieviel genau ist variabel (aber maximal 4K).
Lokale Variablen sind ueblicherweise auf dem Stack... das wird so nicht gehen...
Ist das problematisch wenn ich die 4K auf dem Stack habe und mit anderen Funktionen via Pointer draufschreiben lasse? Irgendwelche negativen Effekte als wenn ich die var global definiere? Ich fand lokal irgendwie "sicherer" als global - da hatte ich Angst, das sich irgendwann über die Zeit unsaubere "Direktzugriffe" auf die Variable einschleichen. mal stark vereinfacht:
1 | void foo(uint8_t *buffer, uint16_t bytes); |
2 | exterm uint8_t magic_function(); |
3 | |
4 | void main() { |
5 | uint8_t data_buffer[4096]; |
6 | uint8_t numbytes; |
7 | |
8 | numbytes=magic_function(); |
9 | foo(data_buffer, numbytes); |
10 | } |
11 | |
12 | void foo(uint8_t *buffer, uint16_t bytes) { |
13 | for (uint8_t a=bytes; a; a--) |
14 | *buffer++=0xcc; |
15 | } |
Oliver Lehmann schrieb: > Ist das problematisch wenn ich die 4K auf dem Stack habe Kann sein. So große Dinge würde ich nicht lokal anlegen. Mach das Array global, damit es in der Memory Statistik auftaucht. Den Pointer darauf kannst du ja immer noch an andere Funktionen weitergeben, daran ändert sich ja nichts. > Effekte als wenn ich die var global definiere? Ich fand lokal irgendwie > "sicherer" als global Das ist im Prinzip ja auch richtig. Auf einem PC würde ich dich da sofort unterstützen. Aber auf einem µC mit seinen limitierten Speicher Resourcen ist es wichtiger, dass du den Überblick behältst, wieviel SRAM du bereits verbraucht hast. Ein paar uint8_t lokal sind nicht das Problem. Aber 4K sind schon heftig.
Oliver Lehmann schrieb: > Ist das problematisch wenn ich die 4K auf dem Stack habe und mit anderen > Funktionen via Pointer draufschreiben lasse? Was meinst du, was passiert, wenn du plötzlich 4kB auf dem Stack beanspruchst? Muß natürlich kein Problem sein, könnte aber. Das hängt von dem Platz ab, den dein Prozessor - welcher auch immer - für den Stack zur Verfügung hat.
Werner schrieb: > Was meinst du, was passiert, wenn du plötzlich 4kB auf dem Stack > beanspruchst? Muß natürlich kein Problem sein, könnte aber. Weiss nicht was passiert? ;) > Das hängt > von dem Platz ab, den dein Prozessor - welcher auch immer - für den > Stack zur Verfügung hat. ATMega1284
Oliver Lehmann schrieb: > Weiss nicht was passiert? ;) Der Stack "läuft über" und überschreibt andere Variablen im SRAM.
Oliver Lehmann schrieb: > Werner schrieb: >> Was meinst du, was passiert, wenn du plötzlich 4kB auf dem Stack >> beanspruchst? Muß natürlich kein Problem sein, könnte aber. > > Weiss nicht was passiert? ;) Du knallst dir mit dem Stack über die Variablen drüber. Und ab da werden dann keine Wetten mehr darüber angenommen, was genau passiert. Mit ein bischen Glück verändern einfach nur ein paar Variablen ihre Werte und dein Programm rechnet falsch (kann natürlich ein Problem sein, wenn aufgrund dessen die Herz Lungen Maschine ihre Arbeit einstellt). Kann natürlich auch sein, dass mit Zuweisungen an Variablen du die Returnadresse einer Funktion niederbügelst, und der µC nach dem Return unkontrolliert irgendeinen Code ausführt, den du ganz sicher so nicht geschrieben hast. 2.5k sind bei dir offenbar so um die 15%. D.h. die 4K entsprechen in etwa zusätzlichen 25%, die in der Statistik nicht auftauchen. Dein Programm belegt zur Zeit nicht 15% SRAM sondern in Wirklichkeit sind es bereits 40%. 40% sind jetzt noch nicht dramatisch. Bei dieser SRAM Größe würde ich mir bis hinauf zu 90% noch keine Sorgen machen. Aber das ist nicht der springende Punkt. Der speingende Punkt ist, dass rund 25% der SRAM Belegung in der Statistik nicht auftauchen. Wenn also der Compiler irgendwann, bei weiter wachsendem Programm, eine SRAM Belegung von 80% ausgibst, magst du dich noch auf der sicheren Seite fühlen, in Wirklichkeit bist du aber schon weit über der Grenze drüber, an der man noch von einem sicheren Betrieb ausgehen kann.
OK, habs dann global definiert (und noch ne zweite Variable die aber nur aus 9 Byte bestand) Program Memory Usage : 5188 bytes 4,0 % Full Data Memory Usage : 6689 bytes 40,8 % Full Hatte bisher keine Probleme, mich wunderte die Data Memory Usage - aber das ist ja nun erklaert - der Stack wird da nicht mir reingerechnet bei den Analysen.
Richtig. Mein Tipp: Geh auf jeden Fall sicher, dass du Karl Heinzes Post gelesen und verstanden hast.
Oliver Lehmann schrieb: > ... - der Stack wird da nicht mir reingerechnet bei den Analysen. Das würde auch wenig Sinn machen, sonst würde immer Data memory usage: 100% angezeigt ;-)
Oliver Lehmann schrieb: > OK, habs dann global definiert (und noch ne zweite Variable die aber nur > aus 9 Byte bestand) > > Program Memory Usage : 5188 bytes 4,0 % Full > Data Memory Usage : 6689 bytes 40,8 % Full > > Hatte bisher keine Probleme, mich wunderte die Data Memory Usage - aber > das ist ja nun erklaert - der Stack wird da nicht mir reingerechnet bei > den Analysen. weil das im allgemeinen nicht geht. dazu müsste man den Programmlauf selber analysieren, wie sich die Funktionen gegenseitig aufrufen. Das wiederrum hängt aber auch wieder oft von externen Ereignissen ab. Schreibst du eine Funktion, die lokal 10k belegt und die nur dann aufgerufen wird, wenn ein bestimmter Pin auf 1 geht, dann wirken sich diese 10k nie aus wenn der Pin nie auf 1 geht. 2 Funktionen void foo() { uint8_t lokal1[10000]; } void bar() { uint8_t lokal2[10000]; } können den Stack mit 10k Maximum belasten, wenn sie so aufgerufen werden int main() { foo(); bar(); } wird aber foo aus bar heraus aufgerufen void bar() { uint8_t lokal2[10000]; foo(); } dann springt die Stackbelastung auf 20k hoch. Bei minimal anderem Programm. (Beliebige Verkomplizierung ist noch möglich, die immer mehr verschleiert, wieviel Stack tatsächlich gebraucht wird).
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.