Forum: Compiler & IDEs C++ char members in Progmem?


von ●● pit ●. (Gast)


Lesenswert?

Hi,

kann mir evtl. jemand einen Tipp geben, wie man am besten  C++ Members 
(string) ordentlich im Flash ablegen kann?

Geht das so in der Art irgendwie? Hat jemand ein Working Sample?

Danke!

 - pit
1
class Item {
2
private:
3
  const char _label __attribute__((__progmem__));
4
  
5
  // bzw av 4.7 sollte ja das klappen:
6
  const __flash char* _label;
7
8
public:
9
  Item(const char* label) : _label(PSTR(label))
10
  {
11
  }
12
};

von Karl H. (kbuchegg)


Lesenswert?

pit p. schrieb:
> Hi,
>
> kann mir evtl. jemand einen Tipp geben, wie man am besten  C++ Members
> (string) ordentlich im Flash ablegen kann?

Auf einem AVR?

> [c]
> class Item {
> private:
>   const char _label __attribute__((_progmem_));
>
>   // bzw av 4.7 sollte ja das klappen:
>   const __flash char* _label;
>
> public:
>   Item(const char* label) : _label(PSTR(label))
>   {
>   }
> };

Auf einem AVR wird das aber so nicht wirklich was. Das PSTR Makro wird 
vom Aufrufer benutzt um den String ins Flash zu verlagern. Deine Klasse 
hat einen ganz banalen Pointer, von dem die Klasse weiß, dass er ins 
Flash zeigt.

von ●● pit ●. (Gast)


Lesenswert?

Ja AVR, sorry hatte ich vergessen.

Das mit dem PSTR() verstehe ich, ist ja klar.

Mein _label - Member ist auch falsch, das müsste ja ein Pointer sein.
Gibt's einen hübschen Weg, das direkt in C++ zu lösen,
ohne irgendwo separat Strings in einem h file oder dgl. zu definieren?

Muss das Argument des Konstruktors auch __flash bekommen?
Die GCC-Doku ist das leider etwas dürftig.

von cppler (Gast)


Lesenswert?

Also Du willst ja nun nicht wirklich eine Stringklasse ins Flash packen 
sondern lediglich Deine Texte.
Wenn Du mit << arbeitest würde ich einfach eine Klasse schreiben die den 
Operator überlädt und gegen die Flashlesebefehle mapt.
Oder willst Du was anderes erreichen ?

von ●● pit ●. (Gast)


Lesenswert?

Ja aber nur die String Konstanten.
Brauche also keinen Operator oder so dafür.

Eigentlich will ich wissen, wie ich Deklaration und Initialisierung 
einer
im Flash abzulegenden Member-String-Konstante trennen kann  - oder?

von cppler (Gast)


Lesenswert?

pit p. schrieb:
> Eigentlich will ich wissen, wie ich Deklaration und Initialisierung
> einer
> im Flash abzulegenden Member-String-Konstante trennen kann  - oder?

Indem Du das C-Beispiel aus dem Tutorial in einer Klasse kapselst:
1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3
 
4
const char pgmString[] PROGMEM = "Hallo world";
5
 
6
void foo (void)
7
{
8
  char string[40];
9
 
10
  strcpy_P (string, pgmString);
11
}

also z.B. sowas daraus machst:
1
class Item
2
{ 
3
  public char string[40]; 
4
  public Item(const char *label)
5
  {
6
   strcpy_P (string, pgmString);
7
   label = string;
8
  }
9
  public ~Item(const char *label)
10
  {
11
   label = NULL;
12
  }
13
}

Sobald Du nun eine neue Klasse erzeugt hast steht in label die Adresse 
des gefüllten char Arrays.
Nur würde ich an Deiner Stelle lieber den << Operator überladen und 
damit direkt auf das Array im Flash zugreifen.
Außerdem wird das ziemlich Speicherintensiv wenn Du für jeden String 
eine eigene Klasse definierst.

von Karl H. (kbuchegg)


Lesenswert?

cppler schrieb:

> Sobald Du nun eine neue Klasse erzeugt hast steht in label die Adresse
> des gefüllten char Arrays.

Ich denke nicht, das das die Idee hinter der Klasse des TO ist.

Die Idee dürfte sein, über einen Flash-String eine Klasse zu stülpen, so 
dass die Klasse beim Zugriff auf den String die Flash-Dereferenzierung 
automatisch macht.

Ich hab aber auch keine vernünftige Idee, wie man das Verlagern in den 
Flash so erzwingen kann, dass derjenige, der die Klasse benutzt, die 
Angabe von PSTR in der Verwendung des Konstruktors nicht vergessen kann.

Ziel dürfte wohl irgendwas in der Richtung sein
1
int main()
2
{
3
  FlashString str1( PSTR( "Hallo World" ) );
4
5
  ... str1 liegt im Flash. Egal wo str1 benutzt wird, holt sch die Klasse
6
      den String aus dem Flash
7
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

pit p. schrieb:
>   // bzw av 4.7 sollte ja das klappen:
>   const __flash char* _label;

Nein.  C++ ist keine Obermenge von Embedded-C (ISO/IEC TR 18037).

von ●● pit ●. (Gast)


Lesenswert?

Argl, stimmt __flash geht ja gar nicht in C++.

von cppler (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Die Idee dürfte sein, über einen Flash-String eine Klasse zu stülpen, so
> dass die Klasse beim Zugriff auf den String die Flash-Dereferenzierung
> automatisch macht.

OK dann habe ich das falsch verstanden.
Allerdings macht sowas bei µCs meiner Meinung nach keinen Sinn, denn er 
legt dann ja für jeden im Flash abzulegenden String eine neue Klasse mit 
an, die wo liegt ?
Also wenn er nun mit einem Schlag das label gleich als Flashstring haben 
will OHNE Leerzeichen wohlgemerkt müßte es doch einfach so gehen:
1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
3
4
public class pgmlabel
5
{
6
 private const char* labelpointer;
7
 pgmlabel(const char* label)
8
 {
9
  PSTR(label);
10
  labelpointer = label;
11
 }
12
 const char* get()
13
 {
14
  return labelpointer
15
 }
16
}
Macht für mich aber immer noch keinen richtigen Sinn, weil ich ja den 
Pointer ins Flash immer noch dereferenzieren muß.
Oder habe ich immer noch nicht verstanden was das eigentliche Problem 
ist ?
Ich würde meine Strings in einem extra Header als PROGMEM Arrays 
definieren und dazu dann defines die als label dienen, dann einfach eine 
Klasse schreiben die den << überlädt das nun indiziert auf's Flash 
zugegriffen wird und die defines dieser Klasse als Parameter übergeben.

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.