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


von gast (Gast)


Lesenswert?

Hallo.
ich habe eine frage zu Variablen im Speicher.
Ich verwende ein LCD, und möchte die Strings im flash speichern.
1
const char menu_item_01[] PROGMEM = "Hauptmenu";
2
const char menu_item_02[]...
3
4
const char* MenuItemPointers[] PROGMEM = {menu_item_01, menu_item_02, ...};
5
6
void main(void)
7
{
8
    char menu_line[5] [20];
9
    strcpy_P(menu_line[0], (char*)(pgm_read_word( &(Hauptmenu[0]) ) ) );
10
    LCD_PutStr(10,110, &menu_line[0] [0]);
11
}

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

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

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

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.

von Stefan E. (sternst)


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.

von gast (Gast)


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 ?!

von gast (Gast)


Lesenswert?

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

von Stefan E. (sternst)


Lesenswert?

gast wrote:

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

Warum?

von Stefan E. (sternst)


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)

von gast (Gast)


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.

von ... (Gast)


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.

von gast (Gast)


Lesenswert?

genau. folglich Variante 1: 2 x speicher im Flash.

von Stefan E. (sternst)


Lesenswert?

gast wrote:
> genau. folglich Variante 1: 2 x speicher im Flash.

NEIN. Wie kommst du nur darauf?

von gast (Gast)


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)

von Stefan E. (sternst)


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
1
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
1
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.

von gast (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.