Datenspeicher überfüllt - wie effektiv nutzen / programmieren?

Gast #800040
Lesenswert?

Hallo Leut's;

ich habe einen ATTiny45 programmiert (im AVR Studio 4.13 mit GCC) um 
mein Prog zu schreiben. Nach dem kompilieren steht unter Memory Usage: 
Programm/ Data/ Eeprom - Speicher, dass mein Data Speicher zu 107,3% 
genutzt wird.

Ich möchte natürlich diesen Speicher reduzieren auf unter 100%. Die 
Frage ist: wie man generell Speicher-sparsam programmiert und auf 
unnütze Variablen verzichten kann. Was trägt zur Speicherreduzierung 
bei? Ich konnte in den Beiträgen zwar was über Speicher lesen, aber 
nicht wie man sprsam damit umgeht.

Wie sieht es bezüglich des Speicherbedarfs aus mit globalen Variablen 
oder mit Hilfsvariablen wei folgt:
1
uint8_t Zeit_180ms = 88;
2
uint8_t Zeit_100ms = 50;
3
uint16_t Strom_Nenn = 420;
4
...
Ich habe mal versucht z.B. die 16 Bit Variable in eine 8 Bit Variable zu 
verändern (natürlich auch die "420" auf unter 255 zu setzen) oder aber 
die Hilfsvariablen auszukommentieren und die Zahlen direkt zu verwenden 
oder globale Variablen in das Hauptprogramm zu verschieben. Aber 
irgendwie hat es nicht wirklich viel gebracht außer das ich jetzt 272 
byte (106,3%) verwenden.

Hat jemand Tipps oder einen Link zu einem Artikel wie man 
Speichersparsam programmiert? Was sollte man im Hinterkopf behalten 
während der Programmierung?

P.S.: Ich weiß, ich weiß. Wenn ich einen ATTiny 85 verwenden habe ich 
keine Probleme mit dem Speicher. Es geht mir mit diesem Thread nicht um 
die µC sondern wirklich um die tatsache der effizienten Progranmmierung 
bezüglich des vorhandenen Speichers.

Wäre für konstruktive Antworten dankbar.
Gast #800053
Lesenswert?

Hallo Janis,

kennst Du Dich mit Assembler aus? Du kannst Dir in AVRStudio, wenn Du 
den Simulator benutzt, mit View/Disassembler ansehen, was der Compiler 
aus Deinem Code gemacht hat. So kannst Du lernen, wann und wie RAM 
belegt wird.

Mit uint8_t liegst Du schon recht gut gut. Vielleicht lassen sich in 
Schleifen usw. auch "register" Variable benutzen. Was für 
"Nebenwirkungen" die verschiedenen Compiler-Optimierungsstufen 
hinsichtlich der RAM-Nutzung haben, habe ich noch nicht probiert. Wäre 
vielleicht einen Versuch wert.

Gruß

Fred

P.S. Versuche möglichst wenige geschachtelte Funktionsausrufe zu 
benutzen, da dafür immer RAM gebraucht wird.
Gast #800076
Lesenswert?

Hallo Janis,

noch ein Idee: Hast Du "-mtiny-stack" in den Compiler Optionen 
eingestellt? Falls nicht, verwendet der Compiler 16 bit für die 
Stack-Addressierung, so dass diese Adressen als 2 Bytes im RAM (bzw. auf 
dem Stack selbst) landen. Falls Du es probierst und dann später doch zum 
Attiny85 wechseln solltest: vergiss dann nicht, diese Option wieder zu 
entfernen!

Gruß

Fred
#800078
Lesenswert?

Jannis wrote:

> Ich habe mal versucht z.B. die 16 Bit Variable in eine 8 Bit Variable zu
> verändern (natürlich auch die "420" auf unter 255 zu setzen) oder aber
> die Hilfsvariablen auszukommentieren und die Zahlen direkt zu verwenden
> oder globale Variablen in das Hauptprogramm zu verschieben. Aber
> irgendwie hat es nicht wirklich viel gebracht außer das ich jetzt 272
> byte (106,3%) verwenden.


Ja, das ist klar. Einzelne Variablen zu optimieren bringt fast nichts.

Besser ist es, überall da, wo globale Variablen unnötig sind, sie lokal 
anzulegen.

Die größte Optimierung ist jedoch bei Arrays möglich, die schlagen ja in 
voller Länge zu Buche.
Und beim GCC werden ohne spezielle Syntax auch alle Konstantenarrays im 
SRAM abgelegt.



Peter
Gast #800079
Lesenswert?

Ich nochmal,

Trägt folgender Code zu Speichernutzung bei?
1
uint8_t Zeit_500 = 245;
2
[...]
3
if (Zeit >= Zeit_500)
4
  [...]

Ich will damit den Code übersichtlich halten. Die Variable wird im Prog 
nicht verändert und behält den Wert.

Kann ich das gleiche auch mit diesem Code erreichen?
1
#define Zeit_500 245;
2
[...]
3
if (Zeit >= Zeit_500)
4
  [...]
Oder wird dann die Zahl 245 als Text 245 benutzt?

Wenn nicht, wird dadurch der Datenspeicher entlastet?
Gast #800084
Lesenswert?

@Andreas Kaiser

>Der Compiler produziert ein Map-File, in dem die Speicherbelegung
>aufgeschlüsselt wird. Das ist bei der Suche die erste Adresse.

Das kann ich nicht bestätigen. Bei mir werden folgende Files produziert: 
*.elf, *.eep, *.hex; *.aps, *.aws

@Fred S.

>noch ein Idee: Hast Du "-mtiny-stack" in den Compiler Optionen
>eingestellt?

nein habe ich nicht, kann ich aber ausprobieren...
#800085
Lesenswert?

Jannis wrote:
> Wie sieht es bezüglich des Speicherbedarfs aus mit globalen Variablen
> oder mit Hilfsvariablen wei folgt:
>
1
uint8_t Zeit_180ms = 88;
2
> uint8_t Zeit_100ms = 50;
3
> uint16_t Strom_Nenn = 420;
4
> ...

wenn sich diese Werte nie ändern, dann kannst du das ersetzen durch

#define Zeit_180ms  88
#define Zeit_100ms  50
#define Strom_Nenn  420

> Ich habe mal versucht z.B. die 16 Bit Variable in eine 8 Bit Variable zu
> verändern (natürlich auch die "420" auf unter 255 zu setzen) oder aber
> die Hilfsvariablen auszukommentieren und die Zahlen direkt zu verwenden

mit den #define machst du im Grunde nichts anderes, allerdings
in einer etwas besseren Form, als wie wenn die Zahlenwerte direkt
im Code stehen würden.

> oder globale Variablen in das Hauptprogramm zu verschieben.

Das bringt nicht viel.
Globale Variablen wirst du nur dann los, wenn sie nicht wirklich
global sein müssen und in Subfunktionen verfrachtet werden können.

Zeig mal dein Programm. Speichersparen ist meist eine
Gratwanderung, die man am realen Code machen muss.

PS: Selbst wenn du den Speicher auf knapp unter 100% bringen
kannst, reicht das noch nicht. Es muss schon deutlich unter
100% sein, da ja zur Laufzeit für Call/Return Stack und
lokale Variablen auch noch Speicher benötigt wird.
#800088
Lesenswert?

Jannis wrote:

> Das kann ich nicht bestätigen. Bei mir werden folgende Files produziert:
> *.elf, *.eep, *.hex; *.aps, *.aws

Muss man möglicherweise im Studio in den Projekteigenschaften noch 
einschalten.

>>noch ein Idee: Hast Du "-mtiny-stack" in den Compiler Optionen
>>eingestellt?


Das spart ein paar Bytes Code, aber keine Daten.
Gast #800090
Lesenswert?

Jannis wrote:
>>Der Compiler produziert ein Map-File, ...
> Das kann ich nicht bestätigen. ...

Dann setze mal bei den Compiler-Optionen (erstes Fenster, wenn Du 
"configuration options" im Studio anklickst) ein Häkchen vor "generate 
map file"! Und den map file dann im Unterordner "default" (oder wohin 
bei Dir der Compiler schreibt) suchen.

Gruß

Fred
Gast #800133
Lesenswert?

>Dir verhagelt der Floating-Point Fehler der aktuellen Version vom WinAVR
>Code und Daten. Es wird am einfachsten sein, wenn du die WinAVR Version
>von Mai 2007 verwendest.

Vielen Dank für die Info, aber ich muss Windows Vista benutzen und bei 
der Mai-Version gibt es da Probleme. Mein Administrator musste mir daher 
die aktuelle Version aufspielen.

Shit - und nu?

ich führe zwei berechnungen it floating point durch:
1
 I_Min = (wert * 0.7); // untere Grenze
2
 I_Max = (wert * 1.3); // obere Grenze

ich brauche aber definitiv die Werte für +/- 30 Prozent, Kann ich anders 
daran kommen?
#800135
Lesenswert?

Jannis wrote:

> Shit - und nu?
>
> ich führe zwei berechnungen it floating point durch:
>
1
>  I_Min = (wert * 0.7); // untere Grenze
2
>  I_Max = (wert * 1.3); // obere Grenze
3
>
>
> ich brauche aber definitiv die Werte für +/- 30 Prozent, Kann ich anders
> daran kommen?


I_Min ist ein Integer?

  Delta = ( wert + 5 ) * 3 / 10;

  I_Min = wert - Delta;
  I_Max = wert + Delta;

(Die + 5 sind die Hälfte von den 10 und sollen eine korrekte
Rundung sicherstellen)

Aufpassen musst du, dass die Berechnung zwischendurch nicht
überlaufen kann. Hängt von wert ab (Datentyp und Wertebereich).
Gast #800159
Lesenswert?

>Dir verhagelt der Floating-Point Fehler der aktuellen Version vom WinAVR
>Code und Daten. Es wird am einfachsten sein, wenn du die WinAVR Version
>von Mai 2007 verwendest.

DEFINITIV

Wenn ich mit ganzen Zahlen rechne habe ich folgendes:
Data:          4 bytes (1.6% Full)

Also ganze 100% weniger

@a-k
Woran hast du das in dem map-file erkannt?

@kbuchegg
Danke für Dein Rechenbeispiel, damit komme ich und auch mein 
Datenspeicher { ;-) } klar. Die Rundungsfehler sind in diesem Beispiel 
nicht soooo wichtig!

Vielen Dank euch allen für eure ausführlichen Informationen.
Mir ist noch wichtig, wie man das im map-file erkennt und vielleicht 
trotz euren Infos, wo man Artikel oder Infos über speicheroptimierte 
Programmieren findet.
Denn ich interessieren mich generell für einen sauberen Programmierstil, 
weil ich mehr oder weniger gerade erst anfange und von Anfang an grobe 
Fehler vermeiden möchte, die sich sonst ins Hirn brennen und später nur 
noch schlecht loszuwerden sind!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren