Forum: Mikrocontroller und Digitale Elektronik was verbraucht mein Data Memory?


von Oliver L. (ollil)


Lesenswert?

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?

von Manuel W. (other)


Lesenswert?

Hallo,


1.) Ist die Variable global oder lokal definiert?

2.) Wird die Variable bereits verwendet?


Grüße Manuel.

von Oliver L. (ollil)


Lesenswert?

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).

von Purzel H. (hacky)


Lesenswert?

Lokale Variablen sind ueblicherweise auf dem Stack... das wird so nicht 
gehen...

von Oliver L. (ollil)


Lesenswert?

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
}

von Karl H. (kbuchegg)


Lesenswert?

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.

von Werner (Gast)


Lesenswert?

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.

von Oliver L. (ollil)


Lesenswert?

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

von avr (Gast)


Lesenswert?

Oliver Lehmann schrieb:
> Weiss nicht was passiert? ;)
Der Stack "läuft über" und überschreibt andere Variablen im SRAM.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Oliver L. (ollil)


Lesenswert?

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.

von Simon K. (simon) Benutzerseite


Lesenswert?

Richtig. Mein Tipp: Geh auf jeden Fall sicher, dass du Karl Heinzes Post 
gelesen und verstanden hast.

von ... (Gast)


Lesenswert?

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 ;-)

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.