Forum: Mikrocontroller und Digitale Elektronik Xmega Strings im Flash?!


von Gusi (Gast)


Lesenswert?

Hi, ich habe ein Problem. Ich habe eine Menüführung auf den klassischen 
16x02 Displays HD44780. Soweit ist alles klar, läuft am Mega. Geht. 
Jetzt habe ich es auf den Xmega umgebaut, da ich mehr power brauche bzw. 
mehr Hardwareschnittstellen. Der gleiche Code angepasst entsprechend 
läuft an sich, aber die Menüs no chance.


Das Array für die Menüs wird nur bis Einrag 5 angesprochen, dann springt 
er zur nächsten Sprache. Wieder 5 weiter, nächste Sprache. Die letzten 2 
Sprachen kann ich gar nicht erreichen, da ist er dann im Nirvana. Alles 
was hinter Weiche RCN-213 ist, egal welche Sprache, ist ebenfalls nicht 
erreichbar. Ausgeben mache ich wie folgt:


lcd_string_p(&displayMenus[language][index], 0, LINE2, FALSE);


Was könnte das sein? Wo ist der Denkfehler?! Warum geht es beim Mega?

1
const unsigned char displayMenus[LANGUAGES][MENUES][LENGHT_DISPLAY] PROGMEM =
2
{
3
  {{"Kurzschlusszeit"}, {"Stromgrenze"}, {"Stufenkurzschl."}, {"Abtastzeit"}, {"Weiche RCN-213"}, {"Kurze Lokaddr."}, {"RailCom BiDiB"}, {"Umschaltzeit"}, {"Neustarten"}, {"Sprache"}, {"Hilfe"}, {"Version"}},
4
  {{"Short time"}, {"Current limit"}, {"Stage shorts"}, {"Sampling"}, {"Switch RCN-213"}, {"Short locoadress"}, {"RailCom BiDiB"}, {"Switchover"}, {"Short restart"}, {"Language"}, {"Help"}, {"Version"}},
5
  {{"Korte tijd"}, {"Huidige limiet"}, {"Stappen kort"}, {"Monsterneming"}, {"Wissel RCN-213"}, {"Kort locadres"}, {"RailCom BiDiB"}, {"Omschakeling"}, {"Opnieuw te starten"}, {"Taal"}, {"Help"}, {"Versie"}},
6
  {{"Kortslutning"}, {"Nuvaeren graense"}, {"Trin korte"}, {"Proveudtagning"}, {"Skift RCN-213"}, {"Kort adresse"}, {"RailCom BiDiB"}, {"Overgangen"}, {"Genstarte"}, {"Sprog"}, {"Hjaelp"}, {"Udgave"}},
7
  {{"Tiempo corto"}, {"Lim de corriente"}, {"Pasos cortos"}, {"Muestreo"}, {"Cambiar RCN-213"}, {"loco. corta"}, {"RailCom BiDiB"}, {"Commutacion"}, {"Reiniciar"}, {"Lengua"}, {"Ayuder"}, {"Version"}},
8
  {{"Temps court"}, {"Lim de courant"}, {"Les etapes court"}, {"Echantillonnage"}, {"Changer RCN-213"}, {"Adresse courte"}, {"RailCom BiDiB"}, {"Commutation"}, {"Redemarrage"}, {"Langue"}, {"Aider"}, {"Version"}},
9
  {{"Orario ridotto"}, {"Limite di corr."}, {"Piccoli passi"}, {"Campionatura"}, {"Interru. RCN-213"}, {"Breve ind. loco."}, {"RailCom BiDiB"}, {"Commutazione"}, {"Ripresa"}, {"Lingua"}, {"Aiuto"}, {"Versione"}}
10
};

von Andreas B. (bitverdreher)


Lesenswert?

Zu wenig Ram?
Bring die Strings ins Flash oder ins Eeprom.

von Alexxx (Gast)


Lesenswert?

Die <avr/pgmspace.h> hast du included?

Lasse dir mal im Debug-Watch-Fenster das Array anzeigen.
Meines wissens kann man auf die Progmem-Variable nicht wie auf normale
Variable im RAM zugreifen. Man muss zuerst mit strcpy_P() den
Flash-String in einen RAM-Buffer kopieren.
Außerdem muss man noch aufpassen, ob man nicht die Farpointer-Varianten
der Funktionen braucht.
Eventuell noch der Hinweis:
"For Xmega devices, make sure the NVM controller command register 
(NVM.CMD or NVM_CMD) is set to 0x00 (NOP) before using any of these 
functions."

Trennt man die Array-Dimensionen in der Initialisierung nicht mit ";" 
und nur innerhalb mit Komma?

Aber ordne mal deine Menü-Definition klarer an, indem du Tabulatoren 
verwendest und deine einzelnen Strings sauber ausrichtest.
Verwende gestaffelten Einzug für die Array-Dimensionen.
So erkennt man gleich optisch irgendwelche Fehler.

von Wilhelm M. (wimalopaan)


Lesenswert?


von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Zu dem Fehler kann ich nichts sagen, aber lesbarer wird Dein Code,
wenn Du das Array als __flash definierst, vgl.:
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C


Grüßle
Volker

von Gusi (Gast)


Lesenswert?

Hallo,

PROGMEM und avr/pgmspace habe ich natürlich.

Alexxx schrieb:
> Die <avr/pgmspace.h> hast du included?
>
> Lasse dir mal im Debug-Watch-Fenster das Array anzeigen.
> Meines wissens kann man auf die Progmem-Variable nicht wie auf normale
> Variable im RAM zugreifen. Man muss zuerst mit strcpy_P() den
> Flash-String in einen RAM-Buffer kopieren.
> Außerdem muss man noch aufpassen, ob man nicht die Farpointer-Varianten
> der Funktionen braucht.
> Eventuell noch der Hinweis:
> "For Xmega devices, make sure the NVM controller command register
> (NVM.CMD or NVM_CMD) is set to 0x00 (NOP) before using any of these
> functions."
>
> Trennt man die Array-Dimensionen in der Initialisierung nicht mit ";"
> und nur innerhalb mit Komma?
>
> Aber ordne mal deine Menü-Definition klarer an, indem du Tabulatoren
> verwendest und deine einzelnen Strings sauber ausrichtest.
> Verwende gestaffelten Einzug für die Array-Dimensionen.
> So erkennt man gleich optisch irgendwelche Fehler.

Das ist korrekt angelegt, der Versatz optisch liegt hier am Forum, da es 
nicht so breit ist, bei mir im Quellcode sieht es geordnet aus.

von Gusi (Gast)


Lesenswert?

Andreas B. schrieb:
> Zu wenig Ram?
> Bring die Strings ins Flash oder ins Eeprom.

Ist doch im Flash!

von Gusi (Gast)


Lesenswert?

Volker B. schrieb:
> Zu dem Fehler kann ich nichts sagen, aber lesbarer wird Dein Code,
> wenn Du das Array als __flash definierst, vgl.:
> 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C
>
> Grüßle
> Volker

PROGMEM ist der Befehl dazu, __flash ist glaube eine Alternative oder 
alt. Macht aber keinen Unterschied.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Gusi schrieb:
>
> PROGMEM ist der Befehl dazu, __flash ist glaube eine Alternative oder
> alt. Macht aber keinen Unterschied.

Doch, das macht bei der Dereferenzierung einen erheblichen Unterschied, 
da man sich die Krücke mit den pgm_read_xxx() Funktionen erspart -- und 
damit m.M. eine nicht unerhebliche Fehlerquelle. Aber natürlich darf 
hier jeder nach seiner Facon glücklich werden...

Grüßle
Volker

von Gusi (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Lies das hier nochmal genau:
>
> https://www.nongnu.org/avr-libc/user-manual/pgmspace.html

Habe ich doch so.

von Gusi (Gast)


Lesenswert?

Volker B. schrieb:
> Gusi schrieb:
>>
>> PROGMEM ist der Befehl dazu, __flash ist glaube eine Alternative oder
>> alt. Macht aber keinen Unterschied.
>
> Doch, das macht bei der Dereferenzierung einen erheblichen Unterschied,
> da man sich die Krücke mit den pgm_read_xxx() Funktionen erspart -- und
> damit m.M. eine nicht unerhebliche Fehlerquelle. Aber natürlich darf
> hier jeder nach seiner Facon glücklich werden...
>
> Grüßle
> Volker

Wenn ich das mit __flash mache, wie lese ich den String dann aus?

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Gusi schrieb:

> Wenn ich das mit __flash mache, wie lese ich den String dann aus?

So, wie Du es auch machen würdest, wenn das Array im RAM liegen würde:

uint8_t Ch = displayMenus[0][1][2];


Grüßle
Volker

von Mitlesa (Gast)


Lesenswert?

Gusi schrieb:
> Wenn ich das mit __flash mache, wie lese ich den String dann aus?

Muss man aufpassen.

Volker B. schrieb:
> Doch, das macht bei der Dereferenzierung einen erheblichen Unterschied,
> da man sich die Krücke mit den pgm_read_xxx() Funktionen erspart -- und
> damit m.M. eine nicht unerhebliche Fehlerquelle.

Die pgm_read_xxx()-Krücke kann man sich nur sparen wenn der Compiler
neu genug ist. Mit dem alten Winavr geht das "Sparen" nicht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Gusi schrieb:
> Habe ich doch so.

Nein, hast Du nicht.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Mitlesa schrieb:
> Die pgm_read_xxx()-Krücke kann man sich nur sparen wenn der Compiler
> neu genug ist. Mit dem alten Winavr geht das "Sparen" nicht.

Da der TO hier aber explizit keine gcc Version genannt hat, gehe ich von 
der aktuellsten aus (denn leider klappt's bei mir mit dem Hellsehen nach 
wie vor nicht so richtig :-) -- außerdem habe ich genau aus diesem Grund 
auf das Tutorial verlinkt.

Grüßle
Volker

: Bearbeitet durch User
von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Gusi schrieb:

> Was könnte das sein? Wo ist der Denkfehler?! Warum geht es beim Mega?

Es gibt einen großen Unterschied zwischen mega und xmega: Der xmega 
nutzt für den Zugriff aufs Flash das NVM-Modul. Wenn Du zwischenzeitlich 
mit diesem etwas anderes machst, z.B. Signatur- oder Calibration-Bytes 
liest und  anschließend das Command-Register nicht zurücksetzt, dann 
schlägt der nächste Daten-Zugriff aufs Flash fehl.

Grüßle
Volker

von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:
> Gusi schrieb:
>> Habe ich doch so.
>
> Nein, hast Du nicht.

Wie gesagt: lies Dir die Doku nochmal genau durch, und Du wirst einen 
Unterschied feststellen.

von Gusi (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Gusi schrieb:
>> Habe ich doch so.
>
> Nein, hast Du nicht.

Doch! PROGMEM ist FLASH! Die Strings liegen im FLASH!

von Gusi (Gast)


Lesenswert?

Volker B. schrieb:
> Mitlesa schrieb:
>> Die pgm_read_xxx()-Krücke kann man sich nur sparen wenn der Compiler
>> neu genug ist. Mit dem alten Winavr geht das "Sparen" nicht.
>
> Da der TO hier aber explizit keine gcc Version genannt hat, gehe ich von
> der aktuellsten aus (denn leider klappt's bei mir mit dem Hellsehen nach
> wie vor nicht so richtig :-) -- außerdem habe ich genau aus diesem Grund
> auf das Tutorial verlinkt.
>
> Grüßle
> Volker

Korrekt, aktuellste Atmelstudio version

von Wilhelm M. (wimalopaan)


Lesenswert?

Gusi schrieb:
> Wilhelm M. schrieb:
>> Gusi schrieb:
>>> Habe ich doch so.
>>
>> Nein, hast Du nicht.
>
> Doch! PROGMEM ist FLASH! Die Strings liegen im FLASH!

Dann zeigt mal die sections.

von Gusi (Gast)


Lesenswert?

Ich habe "den Fehler" gefunden. Naja nicht richig. Mache ich den String 
ein Zeichen kleiner (also 15 Zeichen max. statt 16 wie das Display). 
Geht es.

Jetzt die Frage: Warum?!

von Gusi (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Gusi schrieb:
>> Wilhelm M. schrieb:
>>> Gusi schrieb:
>>>> Habe ich doch so.
>>>
>>> Nein, hast Du nicht.
>>
>> Doch! PROGMEM ist FLASH! Die Strings liegen im FLASH!
>
> Dann zeigt mal die sections.

Ich kann die hex hier hochladen, dann siehst du es, dass die da drin 
liegen. Außerdem, mit/ohne PROGMEM steigt entweder der RAM verbrauch 
(ohne PROGMEM) oder mit PROGMEM steigt der Flash verbrauch.

Ich mache das schon ewig so, das ist korrekt, wird auch bei dem Link so 
angezeigt was hier gepostet wurde: 
https://www.nongnu.org/avr-libc/user-manual/pgmspace.html

PROGMEM ist der Befehl für Flash
EEMEM ist der Befehl für EEPROM

Um da Sachen abzulegen. Sonst gehen die halt in den RAM.

von M. K. (sylaina)


Lesenswert?

Gusi schrieb:
> Ich kann die hex hier hochladen, dann siehst du es, dass die da drin
> liegen.

Würde ich an deiner Stelle auch so machen ;)

Gusi schrieb:
> Ich habe "den Fehler" gefunden. Naja nicht richig. Mache ich den String
> ein Zeichen kleiner (also 15 Zeichen max. statt 16 wie das Display).

Du weist, dass das String-Ende-Zeichen (\0) auch in deinem String 
steckt? Also hat dein Wort 16 Zeichen muss der String 17 Zeichen lang 
sein da das String-Ende-Zeichen mit rein passen muss. ;)

von Gusi (Gast)


Lesenswert?

M. K. schrieb:
> Gusi schrieb:
>> Ich kann die hex hier hochladen, dann siehst du es, dass die da drin
>> liegen.
>
> Würde ich an deiner Stelle auch so machen ;)
>
> Gusi schrieb:
>> Ich habe "den Fehler" gefunden. Naja nicht richig. Mache ich den String
>> ein Zeichen kleiner (also 15 Zeichen max. statt 16 wie das Display).
>
> Du weist, dass das String-Ende-Zeichen (\0) auch in deinem String
> steckt? Also hat dein Wort 16 Zeichen muss der String 17 Zeichen lang
> sein da das String-Ende-Zeichen mit rein passen muss. ;)

Klar, das weiß ich das habe ich gemacht. Ich habe das Problem gefunden. 
Der Compiler hat die Defines nicht angenommen und irgendwas da 
reingesetzt. Jetzt habe ich die Defines unter die Einbindung aller 
Bibliothkene gemacht, statt drüber, jetzt geht es. Aber in keiner 
Bibliothek gibt es Defines mit dem gleichen Namen die zum Redefine 
hätten führen können.

Verstehe ich nicht so ganz ehrlich gesagt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Gusi schrieb:
> Der Compiler hat die Defines nicht angenommen und irgendwas da
> reingesetzt.

Da hast Du ja bestimmt ne Warnung bekommen, wenn er ein Macro 
redefiniert, oder? Oder ...

von Gusi (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Gusi schrieb:
>> Der Compiler hat die Defines nicht angenommen und irgendwas da
>> reingesetzt.
>
> Da hast Du ja bestimmt ne Warnung bekommen, wenn er ein Macro
> redefiniert, oder? Oder ...

Ja. Habe ich. Übersehen. Blöd. Warum er das macht weiß ich dennoch 
nicht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mitlesa schrieb:
> Die pgm_read_xxx()-Krücke kann man sich nur sparen wenn der Compiler
> neu genug ist.

Also nicht älter als 7 1/2 Jahre:  v4.7 Release war Frühjahr 2012.

https://gcc.gnu.org/gcc-4.7/changes.html#avr

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.