Forum: Compiler & IDEs Instanz von class/struct im Flash ablegen


von Spiffman G. (spiffman)


Lesenswert?

Hallo,

ich arbeite gerade an einer Uart-Schnittstelle.
Meine Strings habe ich wie folgt in mein Programm gepackt:
1
const char f_str_0[] PROGMEM = "/?";
2
const char f_str_1[] PROGMEM = "HELP";
3
....
4
const char * const all[] PROGMEM = { f_str_0, f_str_1, ...};
So kann ich über "all" iterieren und alle unterstützten Befehle 
ausgeben.
Je nach Befehl möchte ich eine andere Funktion anspringen.
Alle Funktionen sind zur Compile-Zeit bekannt.
Aktuell habe ich es so gelöst:
1
//Return PIN-Control
2
if( !compare( 4)) {        //Das ist der Index im Array "all"
3
  AllIO.ReturnControl();   //Diese Funktion möchte ich anspringen
4
  uart_puts_P( ">>OK\n\r");
5
  return;
6
}

Das ist natürlich sehr unschön! Da dachte ich machst dir eine Klasse, 
die den String und einen Funktionspointer im Flash enthält.
Dann mach ich mir ein const-Array aller Klasseninstanzen und schupps 
kann ich einfach neue Befehle hinzufügen.
Leider reichen meine C++Kentnisse nicht aus! :-(
Versucht habe ich das:
1
struct PROGMEM UartCommand0P
2
{
3
  const char * const _ptr_text;
4
  const uint8_t (*FunctionToCall)();
5
};
6
7
const UartCommand0P b = { "1", nullptr};
Hier landet der String aber im RAM. :(
1
const UartCommand0P c = { PSTR("blaasdfadsfasdf"), nullptr};
So hätte ich es intuitiv gemacht, jedoch bekomme ich folgenden 
compile-Error:
"statement-expressions are not allowed outside functions nor in 
template-argument lists"

Könnt ihr mir vielleicht sagen, ich ich alles in den Flash packen kann?
Danke für eure Hilfe!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

1) PROGMEM wird nur für Variablen unterstützt, nicht für Typen.

2) In C++ können nur POD (pretty old data) per PROGMEM ins Flash gelegt 
werden.  Nicht-POD liegen immer im RAM (falls sie nicht wegoptimiert 
wurden).

von Rolf M. (rmagnus)


Lesenswert?

Johann L. schrieb:
> 1) PROGMEM wird nur für Variablen unterstützt, nicht für Typen.

Typen gibt es nach dem Compile-Vorgang nicht mehr. Einen Typ kann man 
nicht speichern, was aber auch nirgends versucht wurde.

> 2) In C++ können nur POD (pretty old data)

Eigentlich "plain old data".

> per PROGMEM ins Flash gelegt werden.  Nicht-POD liegen immer im RAM (falls
> sie nicht wegoptimiert wurden).

Und was sollte daran nicht POD sein?

Spiffman G. schrieb:
> struct PROGMEM UartCommand0P
> {
>   const char * const _ptr_text;
>   const uint8_t (*FunctionToCall)();
> };
>
> const UartCommand0P b = { "1", nullptr};

Das Problem dürfte eher PSTR sein, das in C++ nicht funktioniert.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Johann L. schrieb:
>> 1) PROGMEM wird nur für Variablen unterstützt, nicht für Typen.
>
> Typen gibt es nach dem Compile-Vorgang nicht mehr.

Und was soll uns das jetzt sagen?

In der Definition des struct-Typs UartCommand0P steht ein progmem, und 
das wird nicht unterstützt.  Daß der Compiler an der Stelle keinen 
Fehler wirft, bedeutet nicht, daß es unterstützt wird.

Wenn überhaupt gehört das progmem zu den entsprechenden Objekten, etwa b 
oder c.


> Einen Typ kann man nicht speichern, was aber auch nirgends
> versucht wurde.

Dennoch klebt ein progmem dran.

>> 2) In C++ können nur POD (pretty old data)
>
> Eigentlich "plain old data".

> Und was sollte daran nicht POD sein?

Regel 2) gilt unabhängig davon, ab sie im Beispiel verwendet wird.  Ich 
hab lediglich 2 Regeln genannt, die jedes C bzw. C++ Programm 
betreffen.

>> const UartCommand0P b = { "1", nullptr};
>
> Das Problem dürfte eher PSTR sein, das in C++ nicht funktioniert.

In C geht das auch nicht da PSTR nicht in einer Funktion steht. 
Zumindest lässt die Fehlermeldung darauf schießen, daß das 
nicht-compilierbare Codegeschnippsel nicht in einer Funktion steht.

von Rolf M. (rmagnus)


Lesenswert?

Johann L. schrieb:
> Rolf Magnus schrieb:
>> Johann L. schrieb:
>>> 1) PROGMEM wird nur für Variablen unterstützt, nicht für Typen.
>>
>> Typen gibt es nach dem Compile-Vorgang nicht mehr.
>
> Und was soll uns das jetzt sagen?
> In der Definition des struct-Typs UartCommand0P steht ein progmem, und
> das wird nicht unterstützt.  Daß der Compiler an der Stelle keinen
> Fehler wirft, bedeutet nicht, daß es unterstützt wird.

Ah, da hatte ich dich wohl falsch verstanden. Sorry für die Verwirrung.

>>> 2) In C++ können nur POD (pretty old data)
>>
>> Eigentlich "plain old data".
>
>> Und was sollte daran nicht POD sein?
>
> Regel 2) gilt unabhängig davon, ab sie im Beispiel verwendet wird.  Ich
> hab lediglich 2 Regeln genannt, die jedes C bzw. C++ Programm
> betreffen.

Ich sehe nichts im Ursprungsposting, das darauf hindeutet, daß die 
Struktur kein POD sein könnte. Aber du hast natürlich recht, daß man da 
nicht sicher sein kann, wenn nur einzelne Codefragmente gezeigt werden, 
die vermutlich auch noch extra für das Posting geschrieben wurden statt 
dem echten Code.

> In C geht das auch nicht da PSTR nicht in einer Funktion steht.

Ah, wußte gar nicht mehr, daß das nur in Funktionen geht.

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.