Hallo zusammen, Ich habe auf einem ATmega 64 ein Menüsystem implementiert, bestehend aus structs, die einen Pointer auf ihre unter-structs haben. Das ganze wird auf einem LCD dargestellt und man kann in den Menüs navigieren. Mittlerweile ist das Menü ziemlich umfangreich und ich bekomme Probleme mit den strings. Wenn ich in manche Untermenüs gehe, zeigt das LCD nur wilde Zeichen. Es liegt nicht am ATmega64, ich habe schon andere probiert. Ich denke, dass es ein Problem mit den Speicherbereichen gibt, da ich die Größe der einzelnen structs mit ihren Pointern nicht definiere. Jedes struct enthält ja wieder Pointer und ich fürchte, dass der Speicherbereich dafür nicht explizit deklariert wird und dadurch von anderem Code überschrieben. Vielleicht liege ich auch total falsch. Auf jeden Fall brauche ich eine Lösung :) Ich habe ein bisschen Code extrahiert, damit man sieht, wie ichs mache: struct Menu { char *Name; struct Menu *Menus[8]; struct Menu *ParentMenu; uint8_t MenuCount; Function function; } Menu; typedef enum { An, Aus, Rot, Blau, } Function; // Allgemeine Untermenüs (mehrfach verwendet) struct Menu Switch[2]; Switch[0].Name = "An"; Switch[0].MenuCount = 0; Switch[0].function = An; Switch[1].Name = "Aus"; Switch[1].MenuCount = 0; Switch[1].function = Aus; struct Menu Color[2]; Color[0].Name = "Rot"; Color[0].MenuCount = 0; Color[0].function = Rot; Color[1].Name = "Blau"; Color[1].MenuCount = 0; Color[1].function = Blau; // Ebene 1 Menüs struct Menu Haus; // Ebene 2 Menüs struct Menu Haus_Tuer; struct Menu Haus_Fenster; // Ebene 2 zu Ebene 1 zuweisen Haus.Menus[0] = &Haus_Tuer; Haus.Menus[1] = &Haus_Fenster; Haus.MenuCount = 2; Haus_Tuer.Name = "Haustuer"; Haus_Tuer.MenuCount = 2; // Ebene 3 zu Ebene 2 zuweisen Haus_Tuer.Menus[0] = &Switch; Haus_Tuer.Menus[0]->Name = "Schalter"; Haus_Tuer.Menus[0]->MenuCount = 2; Haus_Tuer.Menus[0]->Menus[0] = &Switch[0]; Haus_Tuer.Menus[0]->Menus[1] = &Switch[1]; // Ebene 3 zu Ebene 2 zuweisen Haus_Tuer.Menus[1] = &Color; Haus_Tuer.Menus[1]->Name = "Farbe"; Haus_Tuer.Menus[1]->MenuCount = 2; Haus_Tuer.Menus[1]->Menus[0] = &Color[0]; Haus_Tuer.Menus[1]->Menus[1] = &Color[1]; Haus_Fenster.Name = "Haustuer"; Haus_Fenster.MenuCount = 2; // Ebene 3 zu Ebene 2 zuweisen Haus_Fenster.Menus[0] = &Switch; Haus_Fenster.Menus[0]->Name = "Switch"; Haus_Fenster.Menus[0]->MenuCount = 2; Haus_Fenster.Menus[0]->Menus[0] = &Switch[0]; Haus_Fenster.Menus[0]->Menus[1] = &Switch[1]; // Ebene 3 zu Ebene 2 zuweisen Haus_Fenster.Menus[1] = &Color; Haus_Fenster.Menus[1]->Name = "Farbe"; Haus_Fenster.Menus[1]->MenuCount = 2; Haus_Fenster.Menus[1]->Menus[0] = &Color[0]; Haus_Fenster.Menus[1]->Menus[1] = &Color[1]; // Ebene 0 Menüs struct Menu MainMenu; MainMenu.MenuCount = 1; MainMenu.Name = "MAIN"; // Ebene 1 zu Ebene 0 zuweisen MainMenu.Menus[0] = &Haus; Vielen Dank schon einmal! Grüße Flo
Der Ansatz sieht gut aus. Erste Zeile, die mir komisch vorkommt:
1 | Haus_Tuer.Menus[0] = &Switch; |
Hier würd ich nochmal drüber nachdenken...
Also, jetzt habe ich verstanden, was du damit anstellen wolltest:
1 | // Allgemeine Untermenüs (mehrfach verwendet)
|
und genau das mit dem Mehrfachverwenden geht nicht, außer (a) du kopierst an der entsprechenden Stelle die Sachen um, oder (b) du verwendest die Vorlage wirklich nur in der untersten Ebene. Letzteres hast du offensichtlich vorgehabt, allerdings kann das schon durch den Zeiger ParentMenu nicht mehr funktionieren. Wie du vermutet hast, wird das erste um die fehlenden Daten ergänzte Untermenü überschrieben, sobald du das zweite versorgst. Auch sonst stecken noch ein paar Ungereimtheiten drin. Eins steht aber fest: du wirst dich aber entweder vom Schablonenkonzept verabschieden müssen, oder deine Datenstrukturen so umbauen, daß die Untermenüs in letzter Ebene wirklich identisch bleiben können (dann muß dein Code ohne ParentMenu-Zeiger auskommen), oder aber bei der Initialisierung ein paar memcpys einbauen müssen.
Hallo, Danke für die Antwort, aber ich stimme Dir nicht ganz zu. Ich weise einem Menü ein Untermenü zu und speichere gleichzeitig im Untermenü den Zeiger auf das Menü, damit ich wieder zurück komme. Aus meinem Verständnis sollte das mehrfache zuweisen problemlos gehen, da ich nur den Pointer übergebe. Bisher ging es auch einwandfrei, nur je umfangreicher das Menü wird, umso öfter tritt der Fehler auf. Durch ein paar Tricks konnte ich das bisher lösen, aber jetzt kam ich nicht weiter. Ich denke, es liegt daran, dass der Compiler nicht weiss, wie lang der Text wird und wieviele Untermenüs ich in einem Menü speichern will. Die Anzahl der Untermenüs habe ich dann auf 8 begrenzt. Gerade eben haben ich aus dem char *Name; folgendes gemacht: char Name[9]; und kopiere nun die strings mit strcpy rein. Damit läuft das Menü wieder sauber. Der Compiler sollte jetzt keine Variable mit unbekannter Länge mehr haben und kann so den Platz allokieren. Ich hoffe, dass es ab nun funktioniert, sonst melde ich mich wieder :) Grüße Flo
Flo wrote: #> Ich denke, es liegt daran, dass der Compiler nicht weiss, wie lang der > Text wird Ooch. Character Zählen ist für den Compiler eine der leichtesten Übungen. > Gerade eben haben ich aus dem > char *Name; > folgendes gemacht: > char Name[9]; > und kopiere nun die strings mit strcpy rein. Damit hast du aber die Speicherauslastung nur noch verschlimmert. Deine ursprüngliche Lösung war schon ok. Wenns noch weniger Speicherverbrauch sein soll, dann muss man die Texte in den Flash auslagern. > Der Compiler sollte jetzt keine Variable mit unbekannter Länge mehr > haben und kann so den Platz allokieren. Die hatte er auch so nicht. Die Texte sind sog. String Literale (also Konstante), die der Compiler im SRAM unterbringt. In den Strukturen hast du nur noch Pointer darauf. Ist doch in Ordnung so. PS: durch die Änderung hast du die Texte nicht aus dem SRAM verbannt, die sind immer noch dort (irgendwo müssen sie ja sein). Allerdings werden sie beim Hochfahren des Programmes im Speicher einmal umkopiert, nämlich in die Arrays. Daher residieren die Texte jetzt 2 mal im Speicher :-) Einmal als String-Literal und einmal als Kopie in den Arrays.
> Ich denke, dass es ein Problem mit den Speicherbereichen gibt, da ich > die Größe der einzelnen structs mit ihren Pointern nicht definiere. > Jedes struct enthält ja wieder Pointer und ich fürchte, dass der > Speicherbereich dafür nicht explizit deklariert wird und dadurch von > anderem Code überschrieben. Da brauchst du keine Angst haben. So wie du das gemacht hast, ist das schon in Ordnung. Das einzige: Schmeiss den Parent Pointer raus. So wie du deine Strukturen benutzt, ist der sinnlos. Der Parent-Pointer ergibt sich sowieso dynamisch, durch die Aufrufabfolge der Menüs. Die brauchst du nicht in den Strukturen speichern.
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.