www.mikrocontroller.net

Forum: Compiler & IDEs const prog_char Zeiger


Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
wahrscheinlich stehe ich gerade nur auf dem Schlauch, aber folgender 
Code wirft meinen Compiler aus der Bahn:

flashStrings.h
//! Displays a constant string from flash memory on the lcd
void displayProgString(const prog_char* string);

flashStrings.c
#include <avr/pgmspace.h>
#include "lcd.h"

void displayProgString(const prog_char* string)
{
  unsigned char i = 0;
  for (i = 0; i < 32; i++)
  {
    char c = (char) pgm_read_byte (string);
    if ('\0' != c )
    {
      lcd_write_char(c);
    }
    else
    {
      i = 32;
    }
    string++; 
  }
}

Die Fehlermeldung lautet

../flashStrings.c:2: warning: type defaults to 'int' in declaration of 
'prog_char'
../flashStrings.c:2: error: expected ';', ',' or ')' before '*' token

Es macht auch keinen Unterschied, ob ich die pgmspace.h früher include 
(dort ist prog_char deklariert). Das wundert mich alles, weil ich es im 
Prinzip von 
http://www.roboternetz.de/wissen/index.php/Avr-gcc... 
abgeschrieben habe.

Wahrscheinlich habe ich mich nur unendlich dumm angestellt...

Autor: kosmonaut_pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
du musst in der header-datei auch den datentyp von prog_char 
deklarierbar machen.
aber ich sehe grade, dass du die gar nicht einbindest. irgendwie scheint 
dein beispiel nicht ganz vollständig zu sein.
bye kosmo

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

Bewertung
0 lesenswert
nicht lesenswert
Machs so
void displayProgString(const char* string)

Simpel und einfach.
Möglicherweise hatte prog_char mal eine andere Funktion,
aber so wie die tyepdefs im pgmspace.h liegen, ist prog_char
an dieser Stelle sowieso keine gute Idee.

PS: Deine Schleife in der Funktion ist etwas unübersichtlich.
Wenn die Idee sein soll
   Gib einen String aus, aber nicht mehr als 32 Zeichen
dann schreib das auch so ('Say what you mean')
   i = 0;

   c = (char) pgm_read_byte (string);
   while( c != '\0' && i < 32 ) {
     lcd_write_char( c );
     string++;
     i++;
     c = (char) pgm_read_byte (string);
   }
So hast du die Endbedingung der Schleife an einer Stelle beisammen
und nicht quer über die ganze Schleife verstreut.

Wenn dein C gut ist, dann machst du das so:
   i = 0;

   while( ( c = (char) pgm_read_byte (string)) != '\0' && i < 32 ) {
     lcd_write_char( c );
     string++;
     i++;
   }

oder (wenn dein C 'noch besser' ist) so:
   i = 0;

   while( ( c = (char) pgm_read_byte (string++)) != '\0' && i++ < 32 ) {
     lcd_write_char( c );
   }

Selbst das hier:
  for (i = 0; i < 32; i++)
  {
    char c = (char) pgm_read_byte (string);
    if ( c == '\0' )
      break;

    lcd_write_char(c);
    string++; 
  }

wäre noch besser, da man sich nicht fragen muss, warum in der
Schleife dem i der magische Wert 32 zugewiesen wird.

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Machs so
>
> void displayProgString(const char* string)
>
> Simpel und einfach.

Tut es leider nicht, weil "const char*" ins SRAM gelegt wird. prog_char 
wird von avr gcc zur Verfügung gestellt, um Daten in den Flashspeicher 
auszulagern, die sich nicht mehr ändern. Ich würde gerne auf 
plattformabhängige Casting-Experimente verzichten.

> du musst in der header-datei auch den datentyp von prog_char
> deklarierbar machen.

say what? Wenn du meinst

flashStrings.h
#include <avr/pgmspace.h>
//! Displays a constant string from flash memory on the lcd
void displayProgString(const prog_char* string);

wäre besser, muss ich dich leider enttäuschen, das war mein erster 
Versuch...

Aber ich sehe grade, dass die flashString.h nicht in flashString.c 
included wird... sehr peinlich! Scheint auch den Compiler für's erste zu 
befrieden... Sorry folks, ich habe ja mit eigener Dummheit gerechnet!

Danke für die Denkhilfen!

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

Bewertung
0 lesenswert
nicht lesenswert
Marco wrote:
>> Machs so
>>
>> void displayProgString(const char* string)
>>
>> Simpel und einfach.
>
> Tut es leider nicht, weil "const char*" ins SRAM gelegt wird.

Quatsch.
Der gcc unterscheidet bei einem Pointer nicht ob der jetzt
ins SRAM zeigt oder in den Flash. Für den gcc ist Pointer gleich
Pointer.
Und nichts anderes bekommt die Funktion übergeben.

Das dein Pointer ins Flash zeigt, wird dadurch berücksichtigt,
dass du nicht einfach einen *string machst um an die einzelnen
Zeichen zu kommen, sondern du die Funktion pgm_read_byte benutzt.

Der Datentyp prog_char an dieser Stelle hat höchstens dokumentarischen
Wert um dem Programmierer mitzuteilen, dass der erwartete Pointer ein
Pointer in den Flash sein muss.

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.