www.mikrocontroller.net

Forum: Compiler & IDEs Arrays im Flash beim Atmega


Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein kleines Problem mit Arrays im Flash eines ATmega32. Ich 
nutze AVR GCC als Compiler. Nun zum Problem:

Ich habe eine ganze Reihe Strings im Flash:
const char id06374[] PROGMEM = "Zimmer  7";
const char id06379[] PROGMEM = "Zimmer  9";
const char id06384[] PROGMEM = "Zimmer 11";
const char id06399[] PROGMEM = "Zimmer 21";

nun brauche ich noch ein Array aus einer Structur im Flash was immer 
schön einen 16 bit Wert hat und danach die Adresse zu den obrigen 
'Strings'.

etwa so:
static struct{
  uint16_t Adresse;
  uint16_t* p_auf_ID_string;
} p_adr[] PROGMEM = {6374,id06374,6379,id06379,6384,id06384,6399,id06399};

Das funzt natürlich nicht, war ja klar ;-) .

Könnte mir da jemand weiter helfen? Ich denke ich habe das mit den 
Sectionen im Flash noch nicht begriffen und auch bei Zeigern hapert es 
wohl.

Gruß Rene

Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist,
falsches Forum sollte bei GCC landen.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Rene Zimmermann (renezimmermann)

>Das funzt natürlich nicht, war ja klar ;-) .

Ich glaube da fehlen nur Klammern.
static struct{
  uint16_t Adresse;
  uint16_t* p_auf_ID_string;
} p_adr[] PROGMEM = {{6374,id06374},
           {6379,id06379},
           {6384,id06384},
             {6399,id06399}};

MfG
Falk

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht eher das der Pointer p_auf_ID_string aufs Flash zeigen soll?
So zeigt er ja ins SRAM oder?

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

Bewertung
0 lesenswert
nicht lesenswert
Philipp wrote:
> Nicht eher das der Pointer p_auf_ID_string aufs Flash zeigen soll?
> So zeigt er ja ins SRAM oder?

Das ist dem gcc sowieso egal. Pointer ist Pointer.
Das der Pointer ins Flash zeigt, must du durch die Art
der Verwendung des Pointers berücksichtigen.
Sprich: keine * - Derferenzierung sondern pgm_read_xxx
Funktionen benutzen.

Mal anders gefragt: Wie ist diese Aussage
Das funzt natürlich nicht, war ja klar ;-) .
zu begreifen. Hast du Fehlermeldungen vom Compiler oder
ein Runtime Problem?

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@kbuchegg
Ah, ach so, sorry, kenn das nur so vom IAR... ;)

Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

erst mal Danke für die schnellen Antworten. Ich bekomme die Warnung:
main.c:58: warning: initialization from incompatible pointer type

also hier:
} p_adr[] PROGMEM = {{6374,id06374},{6379,id06379},{6384,id06384},{6399,id06399}};

Noch was zum Verständnis, grundsätzlich sollen beide Arrays im Flash 
liegen. Das erste Array besteht nur aus Strings die auf das LCD 
ausgegeben werden. Das zweite Array hat als erstes die Adresse die über 
den Bus kommt. Selbige wird dann verglichen und wenn sie ausgegeben 
werden soll dann wird über den dazugehörigen Pointer auf den richtigen 
String aus Array 1 zugegriffen. Aber irgendwie habe ich ein Problem mit 
den Zeigern.

Gruß Rene

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

Bewertung
0 lesenswert
nicht lesenswert
>
> static struct{
>   uint16_t Adresse;
>   uint16_t* p_auf_ID_string;
> }
> 

main.c:58: warning: initialization from incompatible pointer type

Na ja. Ein Pointer auf einen String ist ja auch nicht
unbedingt ein uint16_t*;

static struct{
  uint16_t Adresse;
  const char* p_auf_ID_string;
};

das sollte abhelfen.

Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo,
das funzt perfekt, frage mich nur wie oft ich diesen Fehler noch machen 
will. ;-)

Gruß Rene

Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, habe schon wieder ein Problem:
148:                  if (p_adr[z].Adresse == empfDaten.Adresse){
+000004E3:   91200067    LDS     R18,0x0067       Load direct from data space
+000004E5:   91300068    LDS     R19,0x0068       Load direct from data space
+000004E7:   E0E0        LDI     R30,0x00         Load immediate
+000004E8:   E0F0        LDI     R31,0x00         Load immediate
+000004E9:   E6A1        LDI     R26,0x61         Load immediate
+000004EA:   E0B1        LDI     R27,0x01         Load immediate
+000004EB:   918D        LD      R24,X+           Load indirect and postincrement
+000004EC:   919C        LD      R25,X            Load indirect
+000004ED:   9711        SBIW    R26,0x01         Subtract immediate from word
+000004EE:   1782        CP      R24,R18          Compare
+000004EF:   0793        CPC     R25,R19          Compare with carry
+000004F0:   F0C1        BREQ    PC+0x19          Branch if equal

p-adr[] ist ein Array im Flash ab 0x161 aber der Compiler nimmt an das 
es im Ram ist wie man an den LDS/LDI/LD sieht. Wie kann ich das Teil 
dazu bewegen den LPM Befehl zu benutzen?

Gruß Rene

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Sprich: keine * - Derferenzierung sondern pgm_read_xxx
> Funktionen benutzen.

Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Morgen,

ja das habe ich auch schon probiert. Meiner Meinung nach müßte es so 
aussehen:
const char id06374[] PROGMEM = "Zimmer  7";
const char id06379[] PROGMEM = "Zimmer  9";
const char id06384[] PROGMEM = "Zimmer 11";
const char id06399[] PROGMEM = "Zimmer 21";
const char id06427[] PROGMEM = "Zimmer 36";
const char id06438[] PROGMEM = "Zimmer 42";
const char id06522[] PROGMEM = "Zimmer 49";
const char id06612[] PROGMEM = "Zimmer 52";
const char id06637[] PROGMEM = "Zimmer 55";
const char id06645[] PROGMEM = "Zimmer 59";


struct{
  uint16_t Adresse;
  const char* p_auf_ID_string;
} p_adr[] PROGMEM = {  {6374,id06374},{6379,id06379},{6384,id06384},{6399,id06399},{6427,id06427},
            {6438,id06438},{6522,id06522},{6612,id06612},{6637,id06637},{6645,id06645}};

for (uint8_t z=0; z<10; z++){                      // Lese alle möglichen Adressen
  if (pgm_read_word(p_adr[z].Adresse) == empfDaten.Adresse){      // und vergleiche sie mit der empfangenen
    strcpy_P(buffer, pgm_read_word(p_adr[z].p_auf_ID_string));    // wenn gleich, Flashstring in Rambuffer kopieren
    break;                              // wenn Adresse gefunden, Fertig
  }
}
Das gibt aber mal wieder eine Compilerwarnung:
main.c:151: warning: passing argument 2 of 'strcpy_P' makes pointer from integer without a cast

Aber wahrscheinlich habe ich mal wieder nur einen kleinen Fehler 
gemacht.

Gruß Rene

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
pgm_read_word gibt einen integer zurück, aber strcpy_P will natürlich 
einen Zeiger haben.

Ich denke auch, daß du statt:
if (pgm_read_word(p_adr[z].Adresse) == empfDaten.Adresse){
eigentlich neinstest:
  if (pgm_read_word(&p_adr[z].Adresse) == empfDaten.Adresse){

Autor: Rene Zimmermann (renezimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

meinste so?
          for (uint8_t z=0; z<10; z++){                      // Lese alle möglichen Adressen
            if (pgm_read_word(&p_adr[z].Adresse) == empfDaten.Adresse){      // und vergleiche sie mit der empfangenen
              strcpy_P(buffer, (char*)pgm_read_word(p_adr[z].p_auf_ID_string));    // wenn gleich, Flashstring in Rambuffer kopieren
              break;                              // wenn Adresse gefunden, Fertig
            }
          }
Gruß Rene

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja

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.