www.mikrocontroller.net

Forum: Compiler & IDEs Zugriff string Konstante im PROGMEM eleganterer, einfacherer Weg?


Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Nun wird mein SRAM langsam knapp und ich muss meine String Konstanten in 
den PROGMEM verschieben. Derzeit behelfe ich mir so, das geht doch gibt 
es einen eleganteren Weg?
void get_id_name(uint8_t id, char *out) {
  static char strA[] PROGMEM = "Alfons";
  static char strB[] PROGMEM = "Julia";
  static char strC[] PROGMEM = "Seb";
  static char strD[] PROGMEM = "Olaf";
  static char strE[] PROGMEM = "unknown";

  switch (id) {
    case 0: copy_pgmstr_to_ram(strA, out); break;
    case 1: copy_pgmstr_to_ram(strB, out); break;
    case 2: copy_pgmstr_to_ram(strC, out); break;
    case 3: copy_pgmstr_to_ram(strD, out); break;
    case 4: copy_pgmstr_to_ram(strE, out); break;
  }
}

Ich brauche also zu der ID dann einen Zeiger auf die Zeichenkette.
Meine Versuche mit einer direkte Deklaration eines Array funktioniert 
nicht.

Danke für jeden Tip!

Gruß AVRli...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guck dir mal den PSTR-Makro an.

Autor: Laszlo H. (mobius)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erspart dir den char PROGMEM Teil. Eleganter (und schneller) geht es, 
indem du die Zeiger auf die einzelnen Strings in ein Array packst.

static char strA[] PROGMEM = "Alfons";
static char strB[] PROGMEM = "Julia";
static char strC[] PROGMEM = "Seb";
static char strD[] PROGMEM = "Olaf";
static char strE[] PROGMEM = "unknown";

static char strings[] = {
  strA,
  strB,
 ...
};

void get_id_name(uint8_t id, char *out) {
  strcpy_P(out, &(strings[id]);
}


Logischerweise kannst du auch diesen in den PROGMEM legen. Spart dir 
dann je 2 Byte/Eintrag, nur musst du dann vorher auch diesen aus dem 
Flash lesen, siehe [1].

gruß
Mobius

[1] http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Danke für Eure Hinweise.
Ich habe mich nun an das Beispiel gehalten aber das sorgt nun dafür das 
mein Programm nun überhaupt nicht mehr anläuft. :-(

Das wird nun aber auch so in [1] beschrieben.

Ob ich das mit den Zeigern jemals verstehen werde??? :-(

Gruß AVRli...
void get_id_name(uint8_t id, char *out) {

char string_1[] PROGMEM = "String 1";
char string_2[] PROGMEM = "String 2";
char string_3[] PROGMEM = "String 3";
char string_4[] PROGMEM = "String 4";
char string_5[] PROGMEM = "String 5";

PGM_P string_table[] PROGMEM = 
{
    string_1,
    string_2,
    string_3,
    string_4,
    string_5
};

    strcpy_P(out, (PGM_P)pgm_read_word(&(string_table[id])));
}

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Strings stehen so ja auch gar nicht im Flash (und die 
Pointer-Liste auch nicht). Du bekommst doch auch garantiert "attribute 
ignored"-Wanungen vom Compiler. Entweder schreibst du noch ein static 
davor, oder du machst globale Variablen daraus.

PS: Und für die Zukunft merken: Warnungen nicht einfach ignorieren, und 
bei Fragen hier mit angeben.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist nicht klar, warum du nicht den allereinfachsten Weg gehst
void get_id_name(uint8_t id, char *out) {
  switch (id) {
    case 0:  copy_pgmstr_to_ram(PSTR( "Alfons" ),  out); break;
    case 1:  copy_pgmstr_to_ram(PSTR( "Julia" ),   out); break;
    case 2:  copy_pgmstr_to_ram(PSTR( "Seb" ),     out); break;
    case 3:  copy_pgmstr_to_ram(PSTR( "Olaf" ),    out); break;
    default: copy_pgmstr_to_ram(PSTR( "unknown" ), out); break;
  }
}

Das PSTR Makro sorgt dafür, dass der String ins Flash verbannt wird.

Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Mir ist nicht klar, warum du nicht den allereinfachsten Weg gehst

Ja mir wohl auch nicht. :-(
Das ist wirklich ein sehr interessanter Weg! :-D
So konnte ich ohne viel deklarieren meine ganzen Zeichenkette in den 
PROGMEM legen. Gut die ganzen str Funktionen müssen dann natürlich die 
mit _P sein das war aber nicht so schwer.

Satte 30% hab ich im RAM mit Zeichenketten "verballert". Nun im 
Programmspeicher ist noch genügend Platz, auf Geschwindigkeit kommt es 
bei der Anwendung nicht an.

Und nebenbei meine Funktion
copy_pgmstr_to_ram(PSTR( "Alfons" ),  out);

Gibt es ja auch schon, ach wenn man nicht immer das Rad neu erfinden 
würde wollen. Gut ich hab was bei gelernt aber die folgende nehme ich 
nun. ;-)
strcpy_P(out, PSTR( "Alfons" );


Danke!
Gruß AVRli...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@AVRli (Gast)

>Satte 30% hab ich im RAM mit Zeichenketten "verballert". Nun im
>Programmspeicher ist noch genügend Platz, auf Geschwindigkeit kommt es
>bei der Anwendung nicht an.

Aus dem RAM lesen dauert beim AVR 2 Takte (ld), aus dem Flash 3 Takte 
(lpm). Plus den ganzen Schleifenoverhead ist beides annähernd gleich 
schnell.

MfG
Falk

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es denn für Deine Anwendung überhaupt erforderlich, daß die Strings 
ins RAM kopiert werden? Was machst Du dann dort mit den Strings?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.