Forum: Compiler & IDEs Mit einem STRUCT Strings im FLASH ablegen und auslesen?


von Marc L. (marc_l)


Angehängte Dateien:

Lesenswert?

Hallo,

ich arbeite mich gerade in STRUCTS ein.
Ziel ist ein Menü auf einem Grafikdisplay mittels AVR auszugeben.
Mein erstes Menü bestand aus mehreren STRUCTS, in denen die Strings 
auch im FLASH hinterlegt wurden. Das Auslesen hat wunderbar geklappt.
Nun möchte ich aber nur noch ein STRUCT haben, in dem die Strings 
stehen und nicht über eine Art Indexzähler aus einem anderen STRUCT 
geladen werden müssen.
Im Anhang ist mein erster Versuch dazu.

Folgend die Probleme, die ich noch nicht durchschaue...
Beim Compilieren bekomme ich mit:
1
ks0108Puts_P(menu_rom_data[0].menu_text);
keinen Fehler.

Compiliere ich mit
1
ks0108Puts_P(&menu_rom_data[0].menu_text);
dann erscheint folgende Warnung:
1
warning: passing argument 1 of 'ks0108Puts_P' from incompatible pointer type
Es wird aber in beiden Fällen nur ein Zeichenwirrwarr auf dem Display 
ausgegeben.

Könnte mir bitte jemand auf die Sprünge helfen?! Wäre sehr nett!
Das Tutorial hat mir leider nicht sehr weitergeholfen.
Ein Unbeteiligter sieht den Fehler bestimmt schneller als jemand, der 
sich festprogrammiert hat! ;)

Besten Dank,
Marc

von Rolf Magnus (Gast)


Lesenswert?

Was für einen AVR hast du denn? Dein Array braucht ohne die Strings 
schon 4kB Flash.

Marc L. schrieb:
> Folgend die Probleme, die ich noch nicht durchschaue...
> Beim Compilieren bekomme ich mit:
> ks0108Puts_P(menu_rom_data[0].menu_text);
> keinen Fehler.

Warum auch? Die Funktion erwartet einen Zeiger auf char, und du 
übergibst einen solchen.

> Compiliere ich mit
> ks0108Puts_P(&menu_rom_data[0].menu_text);
> dann erscheint folgende Warnung:
> warning: passing argument 1 of 'ks0108Puts_P' from incompatible pointer type

Klar, du übergibst ja nicht mehr einen Zeiger auf char, sondern einen 
Zeiger auf einen Zeiger.

> Es wird aber in beiden Fällen nur ein Zeichenwirrwarr auf dem Display
> ausgegeben.

Das liegt daran, daß du nur die Zeiger auf deine Strings im Flash stehen 
hast, aber nicht die Strings selbst. Die sind ja nicht Teil der 
Struktur.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Strings wie "Drehzhal" werden im RAM abgelegt, nicht im Flash.

von Marc L. (marc_l)


Lesenswert?

Danke für die Antworten!

Rolf Magnus schrieb:
> Was für einen AVR hast du denn? Dein Array braucht ohne die Strings
> schon 4kB Flash.
Sorry, hatte das Array für ein Hauptmenü mit 10 Punkten und 50 
Untermenüs mit jeweils 9 Unterpunkten erstellt.
Ist noch ein Überbleibsel von den mehreren STRUCTS.
Darum möchte ich nur ein STRUCT erstellen, damit es Übersichtlicher und 
speicherschonender wird, da ich dann keine leeren Bereiche als Reserve 
einfügen muss.
Es handelt sich übrigens um einen ATmega1284P.

Rolf Magnus schrieb:
> Das liegt daran, daß du nur die Zeiger auf deine Strings im Flash stehen
> hast, aber nicht die Strings selbst. Die sind ja nicht Teil der
> Struktur.
Klick. Ja, das stimmt.
Aber wie bekomme ich denn die einzelnen Strings in das STRUCT?
Hilft da wirklich nur der Umweg über ein zweites STRUCT? Hoffe nicht.

So sah u.a. ein weiteres STRUCT aus:
1
const unsigned char PROGMEM menu_text[510][20+1] = {
2
// Hauptmenü -----------------------------------------------
3
  {"Text1               "},  // Text Nr. 0
4
  {"Test2               "},  // Text Nr. 1
5
  {"Text3               "},  // Text Nr. 2
6
  {"Text4               "},  // Text Nr. 3
7
  {"                    "},  // Text Nr. 4
8
  {"                    "},  // Text Nr. 5
9
  {"                    "},  // Text Nr. 6
10
  {"                    "},  // Text Nr. 7
11
  {"                    "},  // Text Nr. 8
12
  {"                    "}   // Text Nr. 9
13
};
Wie bekomme ich also dieses STRUCT in das STRUCT vom Anfangspost?
Habe da schon einiges probiert, jedoch alles ohne Erfolg. :(

Johann L. schrieb:
> Strings wie "Drehzhal" werden im RAM abgelegt, nicht im Flash.
Okay, habs mir schon fast gedacht. Wie sieht denn der Aufruf auf, wenn 
man die Strings in den FLASH ablegen will?
Bekomme das irgendie nicht hin. Mit PROGMEM funktioniert das nicht.
Ist vielleicht auch der falsche Ansatz?!

Danke,
Marc

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Marc L. schrieb:
> Johann L. schrieb:
>> Strings wie "Drehzhal" werden im RAM abgelegt, nicht im Flash.
> Okay, habs mir schon fast gedacht. Wie sieht denn der Aufruf auf, wenn
> man die Strings in den FLASH ablegen will?
> Bekomme das irgendie nicht hin. Mit PROGMEM funktioniert das nicht.
> Ist vielleicht auch der falsche Ansatz?!

Also ich kann mir nicht vorstellen, daß du 510 (in Worten: 
fünfhundertundzehn) Menü-Punkte hast!

Davon ab ist es leider nicht so einfach, String-Literals ausserhalb von 
Funktionen in den Flash zu bekommen:
1
const char str1[]  PROGMEM = "str1"; // in Flash
2
const char* str2[] PROGMEM = "str2"; // "str2" im RAM, str2 im Flash
Das muss man umständlich über Zwischenvariablen erlegigen:
1
const char STR_STR2[]  PROGMEM = "str2";
2
const char* str2[] PROGMEM = STR_STR2;

von Rolf Magnus (Gast)


Lesenswert?

Marc L. schrieb:
> So sah u.a. ein weiteres STRUCT aus:
> const unsigned char PROGMEM menu_text[510][20+1] = {
> // Hauptmenü -----------------------------------------------
>   {"Text1               "},  // Text Nr. 0
>   {"Test2               "},  // Text Nr. 1
>   {"Text3               "},  // Text Nr. 2
>   {"Text4               "},  // Text Nr. 3
>   {"                    "},  // Text Nr. 4
>   {"                    "},  // Text Nr. 5
>   {"                    "},  // Text Nr. 6
>   {"                    "},  // Text Nr. 7
>   {"                    "},  // Text Nr. 8
>   {"                    "}   // Text Nr. 9
> };

Struct? Wo? Das ist ein Array.
Du mußt es im Prinzip so machen, wie Johann schreibt, also jeden String 
einzeln mit PROGRMEM definieren, und dann die Zeiger deiner Menüeinträge 
damit initialisieren.

von Karl H. (kbuchegg)


Lesenswert?

Marc L. schrieb:

> Folgend die Probleme, die ich noch nicht durchschaue...
> Beim Compilieren bekomme ich mit:
>
1
ks0108Puts_P(menu_rom_data[0].menu_text);
> keinen Fehler.
>
> Compiliere ich mit
>
1
ks0108Puts_P(&menu_rom_data[0].menu_text);
> dann erscheint folgende Warnung:
>
1
warning: passing argument 1 of 'ks0108Puts_P' from incompatible
2
> pointer type
> Es wird aber in beiden Fällen nur ein Zeichenwirrwarr auf dem Display
> ausgegeben.

Da ist dann auch noch etwas anderes falsch. (Die Sache mit den Strings 
wurde ja schon angesprochen)

Dein menu_rom_data  liegt als solches im Flash. Das bedeutet aber auch, 
dass du darauf nicht mittels menu_rom_data[0] darauf zugreifen kannst um 
dir dann von diesem einen Array Eintrag den Member menu_text zu holen.

Wenn immer Dinge im Flash liegen, muss der Zugriff über die pgm_read_xxx 
Funktionen erfolgen. Dein menu_rom_data liegt im Flash, also musst du 
auch die pgm_read_xxx Funktion dafür benutzen um an den Pointer zu 
kommen, den du dann an ks108Puts_P weitergeben kannst.

von Marc L. (marc_l)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> Compiliere ich mit
>> ks0108Puts_P(&menu_rom_data[0].menu_text);> dann erscheint folgende
>> Warnung:
>> warning: passing argument 1 of 'ks0108Puts_P' from incompatible
>> pointer type
> Da ist dann auch noch etwas anderes falsch.
Ja, und zwar erwartet die Funktion
1
ks0108Puts_P(...);
ein char und kein unsigned char.
So hat es geklappt:
1
const char PROGMEM menu_text[510][20+1] = {

Johann L. schrieb:
> Also ich kann mir nicht vorstellen, daß du 510 (in Worten:
> fünfhundertundzehn) Menü-Punkte hast!
Doch, so war es geplant:
Hauptmenü: 10 Einträge
Untermenü: 1x Maschinenauswahl + 9x Datenbereiche = 10 Einträge
Da ich 50 Maschinen erstellen wollte: Hauptmenü (10) + Untermenüs 
(50*10) = 510 Einträge!
Das habe ich wieder verworfen.

Nun habe ich es wiefolgt gelöst:
Ich habe mir eine Sprungtabelle als STRUCT erstellt.
In der ersten Spalte steht jeweils der Laufindex, den ich dazu verwende 
Strings aus einem Array auszulesen. Das geht sehr gut.
Habe zwei Arrays definiert: einmal den Haupttext, der angezeigt wird und 
einmal den Infotext passend zum Haupttext. Gemanaged wird das über den 
Laufindex.
Und vor allem: Es liegt alles im Flash!

Danke an alle, jetzt ist mir so einiges klar geworden!
Marc

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.