mikrocontroller.net

Forum: Compiler & IDEs Variable im Flash (PROGMEM) verständnis


Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.
ich habe eine frage zu Variablen im Speicher.
Ich verwende ein LCD, und möchte die Strings im flash speichern.
const char menu_item_01[] PROGMEM = "Hauptmenu";
const char menu_item_02[]...

const char* MenuItemPointers[] PROGMEM = {menu_item_01, menu_item_02, ...};

void main(void)
{
    char menu_line[5] [20];
    strcpy_P(menu_line[0], (char*)(pgm_read_word( &(Hauptmenu[0]) ) ) );
    LCD_PutStr(10,110, &menu_line[0] [0]);
}

Das funktionier soweit auch.
Das Array menu_item_01 liegt im Flash.

Aber welchen Vorteil die oben genannte Methode gegenüber der Folgenden:

void main(void)
{
    char menu_line[5] [20];
    strcpy(menu_line[0], "Hauptmenu");
    LCD_PutStr(10,110, &menu_line[0] [0]);
}

Bei der Variante liegt doch der Text auch im Flash, und wird von dort 
verarbeitet.
Vom Gefühl her würde ich sagen, das die untere Methode etwas weniger 
Speicher braucht, da ja auch bei der oberen der Text irgendwo im Flash 
steht, und dann in menu_item_01 geladen wird.
außerdem sollte das untere doch schneller sein.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast wrote:

> Bei der Variante liegt doch der Text auch im Flash, und wird von dort
> verarbeitet.

Nein, er liegt im RAM und wird auch von dort verarbeitet.

> Vom Gefühl her würde ich sagen, das die untere Methode etwas weniger
> Speicher braucht

Im Gegenteil, denn der Text ist dort 2 mal vorhanden. Einmal im RAM und 
im Flash, denn der Text im RAM muss ja auch von irgendwo her 
initialisiert werden.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meine die Nackten Buchstaben.
Mal angenommen sie würden wirklich im RAM liegen, dann würde bei der 
ersten Methode ebenfalls RAM verbraucht werden, und zusätzlich noch 
Flash.
Oder sehe ich den Wald vor lauter Bäumen nicht mehr ?!

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein, quatsch.
Der Text kann nicht im RAM liegen, sonst wäre er nach jedem Ausschalten 
weg.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast wrote:

> Mal angenommen sie würden wirklich im RAM liegen, dann würde bei der
> ersten Methode ebenfalls RAM verbraucht werden,

Warum?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also nochmal:

Variante 1:
Text liegt im Flash.
(und nur dort)

Variante 2:
Text liegt im RAM.
(und zusätzlich im Flash zum Initialisieren des RAM)

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil hier:
"const char menu_item_01[] PROGMEM = "Hauptmenu";"
die Variable geladen wird.

ich denke wir reden an ein einander vorbei.

Der Text selbst, muss ja irgendwo in irgendeinem Speicher liegen, bevor 
er in eine Variable geladen wird.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bei der Variante liegt doch der Text auch im Flash
Ja
> und wird von dort verarbeitet
Nein!

Der String wird von den init-Routinen noch vor dem Aufruf der main 
Funktion in den RAM kopiert und dann von dort verarbeitet. Im Endeffekt 
liegt er also sowohl im Flash als auch im Ram (und wird dann von Dir vor 
der Ausgabe gleich nochmal im RAM umherkopiert)


PS: Du solltest Dir unbeding nochmal die Verwendung von 
Zeichenketten/Strings und Arrays und den Zusammenhang zwischen Bedidem 
anschauen! Deine lokale Variable "menu_line" ist ziemlicher Schwachsinn.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
genau. folglich Variante 1: 2 x speicher im Flash.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast wrote:
> genau. folglich Variante 1: 2 x speicher im Flash.

NEIN. Wie kommst du nur darauf?

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in "menu_line" lade ich den Text rein, welchen ich anzeigen möchte.
das hängt natürlich davon ab, wo man sich in dem Menü befindet.

bei der Variante 1 habe ich das problem, das ich "pgm_read_word" nicht 
an die Funktion "LCD_PutStr" übergeben kann.

> NEIN. Wie kommst du nur darauf?
Der Text an sich muss doch irgendwo im Flash liegen.
wenn das programm startet (init-Routinen), läd er den text in die 
variable "menu_item_01" im Flash. (variante 1)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der Text an sich muss doch irgendwo im Flash liegen.
> wenn das programm startet (init-Routinen), läd er den text in die
> variable "menu_item_01" im Flash. (variante 1)

Die Variable liegt im Flash und enthält bereits den Text (dafür ist es 
ja Flash), da wird beim Programmstart nichts kopiert (wie auch, dazu 
müsste dann ja ins Flash geschrieben werden).

Also mal etwas ausführlicher:

Variante 1:
Der Text "Hauptmenu" steht im Flash und wird in dieser Zeile
strcpy_P(menu_line[0], (char*)(pgm_read_word( &(Hauptmenu[0]) ) ) );
vom Flash in das Array im RAM kopiert.
(Effizienter wäre es, ein modifiziertes LCD_PutStr zu schreiben, das den 
Text direkt aus dem Flash holen kann)

Variante 2:
Der Text steht im RAM und wird in dieser Zeile
strcpy(menu_line[0], "Hauptmenu");
vom RAM ins RAM (Array) kopiert. Zusätzlich steht er auch noch im Flash, 
um den Text im RAM bei Programmstart initialisieren zu können.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan Ernst:
alles klar. jetzt ist der Groschen gefallen.
Das mit der Modifizierten Funktion ist auch ein guter Tipp.
Da werde ich mal drauf zu arbeiten.

Das bedeutet, das der Compiler aus "const char menu_item_01[] PROGMEM = 
"Hauptmenu";" etwa einen Bereich im Flash definiert, in dem schon der 
Text steht.
Bzw. werden die Variablen mit "PROGMEM" nur beim Compilieren definiert, 
und nicht bei jedem Programm Aufruf neu definiert !?

Vielen dank.

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.