mikrocontroller.net

Forum: Compiler & IDEs Structure löschen


Autor: Jens Ziegler (bitman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander. Ich habe ein auf Strukturen basierendes Menü
aufgebaut. Ich habe nun das Problem eines immensen Stack-Bedarfs des
Compilers (arbeite mit CV-AVR, dürfte aber nicht stören). Frage Eins:
Warum eigentlich (kenne mich mit Compilerbau nicht aus)? Kann ich das
umgehen?

Frage Zwei:
Da ich quasi identische Menüs mit lediglich verschiedenen
Ausgabevariablen erstellt habe, liegt es nahe, lediglich einen Menübaum
je Problem zu deklarieren, nur den Zeiger auf die Variable zu ändern und
nur den gerade benötigten Baum zu laden. Dazu müsste ich deklarierte
Strukturen aus dem Speicher entfernen, nachdem ich das Menü nicht mehr
brauche. Geht das?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Immenser Stackbedarf?

Das kann daran liegen, daß Du Deine Strukturen als lokale Variablen
anlegst, die landen auf dem Stack.

Struktur löschen?

Geht so:
struct bla
{
  int suelz;
  char laber;
} fusel;

memset(&fusel, 0, sizeof (struct bla));

// oder

memset(&fusel, 0, sizeof (fusel));

Struktur aus dem Speicher entfernen?

Bei lokalen/automatischen Variablen: Einfach den Gültigkeitsbereich
verlassen, das war's dann.

Andernfalls solltest Du Dir mal dynamische Speicherverwaltung ansehen:
struct bla *pfusel;

pfusel = malloc(sizeof (struct bla));

if (!pfusel)
{
  // Fehlerbehandlung
}
else
{
  pfusel->suelz = 3;

  free(pfusel);
}

Autor: Jens Ziegler (bitman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort. Die Strukturen werden (zwingend) in der Main
Funktion deklariert. In Möglichkeit Eins wird der Speicher gelöscht,
aber nicht freigegeben, oder? Möglichkeit Zwei sieht vielversprechend
aus. Bewirkt, wenn ich das richtig verstehe, dass die Struktur statt im
Stack im Heap gespeichert wird und durch free komplett aus diesem
entfernt wird. Richtig?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Die Strukturen werden (zwingend) in der Main
Funktion deklariert."

Damit landen sie auf dem Stack.

Das ließe sich durch Deklarieren als "static" vermeiden.

Wieso eigentlich "zwingend"?

"In Möglichkeit Eins wird der Speicher gelöscht,
aber nicht freigegeben, oder? "

Richtig erkannt.

"(...) Bewirkt (...) dass die Struktur statt im Stack im Heap
gespeichert wird und durch free komplett aus diesem entfernt wird. "

Auch richtig erkannt.

Bedenke aber bei dynamischer Speicherverwaltung die potentiellen
Probleme der Speicherfragmentierung.

Autor: Jens Ziegler (bitman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Main Funktion fragt zyklisch die Tastenbelegung ab, der
ADC-Interrupt ruft alle Funktionen auf (Auswertung des
Wandler-Ergebnisses, Aktualisierung des aktuellen Menüs usw.) Da der
Zeiger auf das aktuelle Menü global ist, bleibt er nach der Rückkehr
aus der Interrupt-Routine erhalten. Da ich in die Main zurückkehre,
bleibt auch der Menübaum erhalten. Deswegen zwingend. Ich werde aber
erstmal versuchen, eine dynamische Speicherverwaltung zu
implementieren. Mal sehen, ob man das dann anders realisieren kann.

Ich dank dir für die Hilfe!

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeig doch mal ein bischen Code.
Deine ganze Beschreibung des Problems lässt darauf
schliessen, dass du da irgendwas versaust.

dynamische Speicherverwaltung wird dir auch nicht helfen.
Wie auch: Die Menüs müssen irgendwo gespeichert werden.
Ob jetzt auf dem Stack oder im Heap (dynamische Speicherverw.)
ist doch völlig Wurscht. Deswegen wird der Speicherverbrauch
auch nicht kleiner, nur weil du Dinge vom Stack in den Heap
verschiebst. Ganz im Gegenteil: Am Stack hat sich der
Compiler schon um die Speicherverwaltung gekümmert. Im Heap
muss das aber dein Pgm machen. Dazu braucht es Code und was
viel wichtiger ist: Es ist Verwaltungsinformation notwendig.
Die muss natürlich auch irgendwo gespeichert werden.
Also: Mit einem Umstieg auf den Heap senkst du den gesamten
Speicherverbrauch nicht, sondern du erhöhst ihn nur.

Autor: Jens Ziegler (bitman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das gesamte Menü im RAM zu speichern ist nicht möglich. Die Idee ist,
das Menü zu zerteilen. Das Hauptmenü wird geladen. Ruft man ein
Untermenü auf, wird zunächst das Hauptmenü aus dem RAM gelöscht. Dann
wird nur das ausgewählte Untermenü geladen. Umgekehrt analog. Die
gesamte Menüstruktur ist selbstverständlich im Flash hinterlegt. Der
oben angesprochene Zwang, alles im Hauptmenü zu auszuführen, ist
beseitigt. Das Konzept entwickle ich gerade. Ich werde ein
Code-Beispiel vorbereiten und hochladen.
Wie gravierend ist die Speicherfragmentierung einzuschätzen? Wenn das
Menü nicht genutzt wird, kann ich doch den gesamten Heap freigeben und
damit defragmentieren, oder?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum lässt Du die Menüs nicht dort, wo sie sowieso schon gespeichert
sind (im ROM)? Warum müssen Menüs "geladen" werden?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Warum lässt Du die Menüs nicht dort,

Das frag ich mich allerdings auch. Ich denke mal der Löwenanteil
der Menüs werden wohl Texte sein. Und die sind nun wirklich trivial
im Flash-ROM zu halten.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn das Menü nicht genutzt wird, kann ich doch den gesamten Heap
> freigeben und damit defragmentieren, oder?

Ja, wenn du zwischenzeitlich alles freigibst, hast du nie Sorgen mit
der Speicherfragmentierung.

Du hast auch keine Sorgen mit Speicherfragmentierung, wenn du immer
nur gleich große Blöcke allozierst und (in wahlloser Reihenfolge)
wieder freigibst, weil dann jeden neue Belegung den Platz eines alten
Blocks wieder neu benutzen kann.

Autor: Jens Ziegler (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, ich habe die Menüverwaltung komplett dynamisch verwaltet. Es wird 
immer nur das aktuelle Menü in den Heap geladen. Beim Menüwechsel wird 
der Speicher freigegeben und anschließend neu genutzt. Alle Menüs haben 
die gleiche Speichergröße, also ist Fragmentierung kein Problem. 
Redundante Menüstrukturen sind nur einmal im Speicher abgelegt (in 
diesem Fall vier identische Menüs zum Einstellen der Zeiten). Über die 
Pointer-Zuweisung findet die Auswahl des zu ändernden Wertes statt.
Somit ist die Menügröße nur noch durch die Größe des Flash-Speichers 
begrenzt, nicht mehr durch den RAM.
Ziel ist jetzt die Erweiterung um andere Teilmenüs, z.B. die direkte 
Ausgangssteuerung, eine Temperaturregelung u.s.w, um einen kleinen 
Kompaktregler zu entwerfen.

Autor: Jens Ziegler (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab noch einen Zahlendreher beseitigt.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast allerdings immer noch nicht erwähnt, warum du die Menüs 
überhaupt erst ins RAM kopierst, statt sie direkt aus dem Flash zu 
benutzen.

Autor: Jens Ziegler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich  schon:
"Redundante Menüstrukturen sind nur einmal im Speicher abgelegt (in
diesem Fall vier identische Menüs zum Einstellen der Zeiten). Über die
Pointer-Zuweisung findet die Auswahl des zu ändernden Wertes statt."

Heißt soviel wie: Ich definiere einen Pointer auf die Time-Struktur, die 
angezeigt werden soll und einen auf den Wert, der in der Struktur 
verändert werden soll. Dann initialisiere ich die Menüstruktur. Die 
Alternative wäre, alle Menü-Strukturen im Flash zu initialisieren. Dann 
sind aber keine Änderungen an den Pointern wie oben beschrieben mehr 
möglich ( Error: unmodifiable value). Und das bedeutet, ich habe jede 
Menge redundanten Code.
(Stell dir vor, meine Zeitschaltuhr soll z.B. 24 Schaltzeiten erlauben. 
Dann müsste ich 24 * 3 = 72 Menü-Strukuteren speichern. So muss ich nur 
die load_Menu Funktion um einige Case Anweisungen erweitern.)
Oder hinkt da mein Denkansatz?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Oder hinkt da mein Denkansatz?

Der hinkt sogar ganz gewaltig.
Wenn deine Benutzerführung durchsichtig und logisch
aufgebaut ist, dann lässt du den Benutzer auswählen
welche Schaltzeit er verändern möchte (Nr von 1 bis 24)
und ihn dann die Schaltzeit selbst eingeben. Wozu du da
72 Menüs brauchst ist mir rätselhaft.

Deine Menüprogrammierung ist, vorsichtig formuliert,
ziemlich grauslich. Das hängt auch damit zusammen, dass
du Benutzerführung und davon ausgelöste Aktionen nicht
sauber voneinander trennst.

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.