Pointer auf String im Flash

Gast #366390
Lesenswert?
• ▲
▼
Hallo,
ich habe ein Problem mit dem zeichenweise auslesen eines Strings aus
dem Flashspeicher eines AVR.
Den Text im Flash habe ich so angelegt:
1
const char h1[] PROGMEM= "Hallo, ich bin aus dem Flash";
Die Zeichen sollen über die serielle Schnittstelle ausgegeben werden,
was ich bis jetzt so gemacht habe:
1
for (i = 0; i < strlen_P(h1); i++) {
2
  zeichen = pgm_read_byte(&(h1[i]));   
3
  uputchar(zeichen);
4
}
So funktioniert es. Normalerweise mache ich sowas in einer Funktion mit
Pointerarithmetik, was jedoch nicht funktioniert:
1
char *ptr_h1;
2
ptr_h1 = h1;
3

4
while (*ptr_h1) {
5
  zeichen = pgm_read_byte(ptr_h1);  
6
  uputchar(zeichen);
7
  *ptr_h1++;
8
}
Dann werden bei mir teilweise Zeichen gesendet die im String h1 so
nicht drinstehen, aber wieso?
Gast #366394
Lesenswert?
• ▲
▼
Irgenwie scheint es einem selber weiterzuhelfen wenn man das Problem
aufschreibt.
Der Fehler liegt bei mir in der Zeile:
while (*ptr_h1)
Das Zeichen kann aus dem Flash ja nur mittels pgm_read_byte ausgelesen
werden. So wie ich es programmiert habe wird er wohl irgendwas aus dem
RAM auslesen bis da zufällig mal eine \0 drinsteht.
Mit
1
while (zeichen = pgm_read_byte(ptr_h1)) {
2
  uputchar(zeichen);
3
  *ptr_h1++;
4
}

geht es jetzt. Trotzdem Danke.
Gast #366395
Lesenswert?
• ▲
▼
1
      while (zeichen = pgm_read_byte(ptr_h1)) {
2
      uputchar(zeichen);
3
      *ptr_h1++;
4
      }

sollte sein
1
      while (zeichen = pgm_read_byte(ptr_h1)) {
2
      uputchar(zeichen);
3
      ptr_h1++;
4
      }

oder kurz
1
      while (zeichen = pgm_read_byte(ptr_h1++))
2
          uputchar(zeichen);
Moderator Persönliche Seite #366397
Lesenswert?
• ▲
▼
Bei *ptr_h1++ ist der * nur sinnlos, da er einen Zeiger
dereferenziert, um das Ergebnis danach wegzuwerfen.  Falls
der Zeiger als "volatile" markiert wäre, würde der Compiler
das Dereferenziern sogar wirklich ausführen, so kann er es
wegwerfen.  Wenn er gut ist, schmeißt er noch 'ne Warnung
(computed value is not used oder sowas).
Gast #366398
Lesenswert?
• ▲
▼
Warnung bekomme ich an dem Punkt keine.
An der Zeile
ptr_h1 = h1;
gibts jedoch ein Warning "assignment discards qualifiers from pointer
target type".
Und dies auch wenn ich mal probeweise den Qualifier const weglasse.
Gast #366399
Lesenswert?
• ▲
▼
Typ(const char [] PROGMEM) != Typ(char *);

Da musst du ptr_h1 als PGM_P definieren, dann geht das ohne Warnung.
PGM_P ptr_h1; /* PGM_P: siehe avr/pgmspace.h */

Warum das mit "pgm_read_byte(ptr_h1)" nicht geht ist etwas
komplizierter und liegt daran wie der Flash-Speichertype (und der
Zugriff darauf) über Makros definiert ist. Du solltest hier eigentlich
immer das Format &h1[index] verwenden, auch wenn der index immer fest 0
ist und das Ergebnis aus C Syntax-Sicht identisch ist. Aber wegen der
Art wie AVR-GCC diesen Ausdruck auswertet (und auch muss, sonst würden
es nicht funktionieren) ergibt sich zwingend dieses Format.
1
      while (zeichen = pgm_read_byte(&ptr_h1[0])) {
2
         uputchar(zeichen);
3
         ptr_h1++;
4
      }
Das ist nur etwas mehr Schreibarbeit, die Effektivität des generierten
Maschinencodes leidet darunter nicht, es wird nicht erst 0 zum Zeiger
addiert.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.