Hallo, in einem aktuellen Arduino Projekt würde ich gerne ein Objekt in den Flash legen (Klasse im Anhang). const Word Wort1(12,22,22) PROGMEM; main() { Word Wort1Ram; memcpy_P(&Wort1Ram, &Wort1, sizeof(Word)); } In der Wort1Ram stehen nach dem Kopieren lauter falsche Werte. Nutze ich anstatt einer Klasse eine Struktur passen die Werte. Unterstützt PROGMEM die Ablage von Objekten nicht? Oder stimmt mit dem Code irgendetwas nicht? Gruß Andreas
Naja, eine Struktur, die nur Daten haelt, ist halt was anderes als eine Klasse die Daten und Funktionen beinhaltet. Logischerweise sieht der Speicher mit der Struktur anders aus, als mit der Klasse. Wenn du wirklich das Objekt speichern willst, dann musst du dich mit serialisierung beschaeftigen. https://de.wikipedia.org/wiki/Serialisierung
Ok dann werde ich mir das genauer ansehen. Vielen Dank für die Info.
Kaj G. schrieb: > Naja, eine Struktur, die nur Daten haelt, ist halt was anderes als eine > Klasse die Daten und Funktionen beinhaltet. Das stimmt zwar, ist hier aber überhaupt nicht das Problem. Das Problem ist vielmehr, dass die Instanz einer Klasse ein Referenztyp ist, die Instanz einer Struktur aber ein Wertetyp. Diese beiden Grundtypen werden vom Compiler völlig unterschiedlich gehandhabt. Das ist ein leicht zu begreifender Unterschied für Assembler-Programmierer, denen die Indirektion als Werkzeug im Blute liegt, aber schwer zu begreifen für Leute, die nur mit Hochsprachen umgehen, denn diese bemühen sich ja gerade, Indirektionen vor dem Anwender zu verbergen. Klappt halt nur nicht immer...
c-hater schrieb: > Das Problem > ist vielmehr, dass die Instanz einer Klasse ein Referenztyp ist Das ist in Java so, aber nicht in C++. Das Problem ist, dass der Compiler im Konstrukturaufruf nicht weiß, dass das eine PROGMEM-Instanz ist. Es ist also mehr ein Problem der AVR-Architektur. Auf ARM würde das Beispiel so problemlos funktionieren, und memcpy_P wäre da auch nicht nötig. Mit einem "constexpr"-Konstruktur und -Instanz würde es vielleicht gehen (ausprobieren). c-hater schrieb: > aber schwer zu begreifen für Leute, die nur mit Hochsprachen > umgehen Die meisten Hochsprachen sind halt nicht für getrennte Adressräume konzipiert. C(++) auf solchen Controllern ist daher problematisch. Kaj G. schrieb: > Wenn du wirklich das Objekt speichern willst, dann musst du dich mit > serialisierung beschaeftigen. Dazu gibt's hier auch einen Artikel: Serialisierung. Ist aber so wahrscheinlich eher nicht nötig.
Mir scheint es auch erst mal so als würde der Konstruktor Probleme machen. Wenn ich eine Struktur verwende, liegt die Tabelle sauber initialisiert im Flash. Genau wie ich es eigentlich erwarte. Mit der Variante als Objekt und der Compiler Option -Wall erhalte ich folgende Fehlermeldung: uninitialized variable 'WordsTable' put into program memory area [-Wuninitialized]. Passt zu dem was ich im Flash sehe, nämlich nur Nullen. Struktur:
1 | struct sDisplayWord { |
2 | byte Column; |
3 | byte Row; |
4 | byte Length; |
5 | };
|
Tabelle:
1 | const DisplayWords::sDisplayWord DisplayWords::WordsTable[] PROGMEM |
2 | {
|
3 | {1,2,4}, |
4 | {5,6,7}, |
5 | };
|
Map Datei: .progmem.data._ZN12DisplayWords10WordsTableE 0x00000068 0x6 DisplayWords.o 0x00000068 _ZN12DisplayWords10WordsTableE Memory Dump siehe Anhang. Die Klasse habe ich schon angepasst und den Konstruktor als constexpr deklariert. Leider hat das noch nicht geholfen. Hat jemand noch eine Idee wie man die Klasse erweitern könnte, damit es funktioniert? Gruß Andreas
Andreas Burnickl schrieb: > Die Klasse habe ich schon angepasst und den Konstruktor als constexpr > deklariert. Leider hat das noch nicht geholfen. Hat jemand noch eine > Idee wie man die Klasse erweitern könnte, damit es funktioniert? Die Variable Wort1 muss auch mit constexpr markiert werden.
Dr. Sommer schrieb: > Die Variable Wort1 muss auch mit constexpr markiert werden. Super Sache. Es funktioniert. Vielen Dank für die Hilfe! [c] constexpr DisplayWord WordsTable[] PROGMEM { DisplayWord(1,2,4), DisplayWord(5,6,7), }; [/] Außerdem musste ich noch den Destruktor löschen, anderfalls kam der Fehler: "type 'const DisplayWord []' of constexpr variable 'WordsTable' is not literal". Darf solch eine Klasse keinen Destruktor haben? Achja kann ich jetzt ohne bedenken jedes Objekt per memcpy kopieren oder kann es da zu Problemen kommen? Stichwort Serialisierung.
Andreas Burnickl schrieb: > Außerdem musste ich noch den Destruktor löschen, anderfalls kam der > Fehler: "type 'const DisplayWord []' of constexpr variable 'WordsTable' > is not literal". Darf solch eine Klasse keinen Destruktor haben? Korrekt, da darf kein Destruktor sein. Wann soll der auch aufgerufen werden? Andreas Burnickl schrieb: > Achja kann ich jetzt ohne bedenken jedes Objekt per memcpy kopieren oder > kann es da zu Problemen kommen Da du die Daten ja nicht zwischen verschiedenen Controllern austauschst und das alles in einem Programm bleibt ist das schon ok. Wäre es kein AVR bräuchtest du auch kein memcpy, dann würde einfaches kopieren mit = reichen.
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.