www.mikrocontroller.net

Forum: Compiler & IDEs Stringarray im Flash


Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ihr,

ein Anfänger hat ein Problem mit einem Stringarray im Flash.

Randbedingungen:
Compiler Avr-GCC
MCU: Atmega103


-------Code-------

const char text1[] PROGMEM = "Parameter laden   ";
const char text2[] PROGMEM = "Parameter ändern  ";
const char text3[] PROGMEM = "Parameter senden  ";

PGM_P dmenu[9] PROGMEM = { text1, text2, text3};



int main(void)
{


    char buffer[10];

    strcpy_P( buffer, dmenu[1] );

    lcd_putc(buffer)
    for(;;);
}



So funktioniert es, wenn ich nun aber das Array im Progmem nicht direkt 
anspreche [1], sondern über einen Variablenindex [var], dann geht es 
nicht mehr.
Also so:

int main(void)
{
unsigned int disp;
char buffer[10];

   disp=1;
   strcpy_P( buffer, dmenu[disp] );
   lcd_putc(buffer)
   for(;;);

}



Kann mir jemand helfen,was ich falsch mache?

Gruss Günter

Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry,

mit nicht funktionieren meine ich, dass der String der aufs Display 
geschrieben wird versaut ist. Also irgendwelche zeichen, aber nicht die 
gewollten. Also zugriffsfehler im Speicher.

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hier:

dmenu[1]

will etwas aus dem RAM lesen.  Du hast aber explizit gesagt,
daß das im ROM sein solle.  Da mußt Du Dich vorher mit __lpm_inline
drum kümmern, daß es aus dem ROM erstmal in (temporären) RAM
kommt.

Oder aber, Du läßt zwar die Strings selbst im ROM, aber das
Array nicht.  6 Bytes RAM dafür sind ja nicht gerade viel.
Du würdest mehr RAM sparen, wenn Du das nicht erst mit
strcpy_P() in einen temporären RAM-Puffer kopieren müßtest,
sonder gleich ein lcd_putc_P() noch lieferst, das die Strings
direkt aus dem Flash verarbeiten kann.

Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,

nun hast Du mich ganz verwirrt...

Aber trotzdem mal:

Hab die LCD-Routinen von Peter Fleury verwendet. Dort ist ja auch ein 
lcd_puts_p dabei, das ein String stück für stück aus dem Progmem liest 
und dann aufs Display schickt.

Aber auch da hab ich das selbe Problem.
Soll heissen, ich kann mein Stringarray direkt addressieren, in dem ich 
die lcd_putc_p routine, wie auch oben beim strcpy_P, mit ner Zahl als 
Index aufrufe. Aber sobald ich die Zahl mit ner variablen ersetze, 
springt er mir zum Teufel...
Begreif das im Moment noch nicht... wo ist der Unterschied zwischen 
dmenu(2) und dmenu(test), mit test=2;

Oder steh ich jetzt so gnadenlos auf dem Schlauch?

Gruss Günter

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, was Du noch nicht begriffen hast ist, daß Du das
Herauspopeln aus dem Flash grundsätzlich erstmal selbst
vornehmen mußt, wenn Du etwas im Flash ablegst.  Der Compiler
tut das nicht für Dich.  Von daher ist es keine sonderlich
praktische Idee, das Array selbst im Flash anzulegen, sondern
laß für das Array all die PROGMEM & Co weg, dann funktioniert
es.

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für dieses kleine Array kann es schon sinnvol sein, das Array im RAM 
abzulegen. Aber z.B. bei einer komplexen Menu-Struktor sollte das Array 
und der Text im Flash abgelegt werden.

Wenn der Index eine konstante ist (dmenu[2]), kann der Compiler der 
Flash-Adresse einfügen:

lcd_puts_p( dmenu[1] );

Wenn der Index aber eine Variable ist, muss man die Adresse
mittels LPM Befehlen herauslesen:

for (i=0; i<3; i++) lcd_puts_p( PRG_RDW(&dmenu[i]) );

Im <avr/pgmspace.h> gibt es zwar ein PRG_RDB() Makro, aber kein 
PRG_RDW() Makro, ich habe deshalb folgendes definiert:

#define PRG_RDW(a) (PRG_RDB((a))+0x100*PRG_RDB((uint16_t)(a)+1))

Besser wäre allerding wenn man PRG_RDW() als Inline-Asm realiseren würde 
und <avr/pgmspace.h> ergänzen würde.






   p = (char *)PRG_RDW(&menu[menuState].text);
   lcd_puts_p(p);

Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joerg und Peter,

vielen Dank fürs "unter die Arme Greifen"... nun hab ichs geschnallt... 
und siehe da: ES funktioniert! Jubel.

Nochmals Danke....

Grüssle Günter

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.