Forum: Compiler & IDEs Unterscheidung von RAM und Flash Daten per Adresse


von Klaus Hummel (Gast)


Lesenswert?

Eine Frage zu Pointer auf Ram bzw. PROGMEM:

Kann man über die Adresse des Pointers unterscheiden, ob
Daten im RAM oder im PROGMEM liegen? Wie ordnet der gcc
Linker die Daten im Flash an?

Könnte man den Linker so konfigurieren, dass Daten, die im Flash
liegen immer oberhalb der größten RAM Adresse liegen?

Beispiel:
ATmega16 hat 1kByte RAM und 16kByte Flash. Wenn der Linker
die PROGMEN Daten erst oberhalb der Adresse 1024 ablegt, könnte man
zwischen Daten aus dem RAM und Daten aus dem Flash mittels
Pointeradresse unterscheiden.

// .... Beispielcode....

char Text1[] = "Text im RAM";
const char Text2[] PROGMEM = "Text im Flash";

// ...
#define RAMEND 0x45F

void SendText(char *ptr)
{
   if (ptr > RAMEND)
      uart_puts_p(ptr); // Daten liegen im Flash
   else
      uart_puts(ptr); // Daten liegen im RAM
   return;
}

int main(void)
{
   SendText(Text1);
   SendText(Text2);
}


Was haltet ihr von dieser Idee? Klar, die Software wird
Microsekunden langsamer aber das tut meistens sowieso
nicht weh....

Klaus

von Jörg Wunsch (Gast)


Lesenswert?

Nein, das geht so nicht.  Die CPU ist halt Harvard, die hat wirklich
verschiedene Speicherbereiche, die bei gleichen Adressen
unterschiedliches ergeben.

Zwar unterscheidet AVR-GCC intern tatsächlich vermittels eines Offsets
zwischen RAM und ROM, aber das ist nur ein Workaround für GCC's
derzeitige Unfähigkeit, mit Harvard überhaupt umzugehen, und für die
Applikation am Ende transparent.

von Klaus Hummel (Gast)


Lesenswert?

> Nein, das geht so nicht.  Die CPU ist halt Harvard, die hat wirklich
> verschiedene Speicherbereiche, die bei gleichen Adressen
> unterschiedliches ergeben.

Ich habe mich schlecht ausgedrückt, sorry:
Ich weiß, dass die Avrs eine Harvard Architektur besitzen und
arbeite auch exzessiv mit Strukturen und Arrays sowohl im Ram
als auch im Flash.

Wenn ich obige Beispieltexte

   char Text1[] = "Text im RAM";
   const char Text2[] PROGMEM = "Text im Flash";

erzeuge, legt der Linker die Daten z.B. auf folgenden Positionen ab:

Auszug aus der test.sym Datei

   00000054 T __ctors_end
   00000054 T __ctors_start
   00000054 T __dtors_end
   00000054 T __dtors_start
   .....
   000000d8 t Text2

   .....
   00800060 D __data_start
   00800060 D Text1

Dass avr-gcc die Ram Adressen hier mit dem Offset von 0x0800000
anzeigt ist mir bewusst. Meine Software "sieht" den Pointer auf
Text1 nur als Wert 0x60, den Pointer von Text2 als 0xd8.

Mein Frage ist:
Kann ich dem Linker mitteilen, dass er PROGMEM Daten erst ab der
Flash-Adresse 0x45F ablegt und im Flash Bereich 0x0000 bis 0x45F nur
Programmcode ablegt?

Die Linker Option "-Ttext 0x45F" verschiebt immer die ganze Text
Section (Programmcode und PROGMEM Daten).
Im Flash Bereich 0x0000 bis 0x45F liegt dann nichts, was natürlich
Flash-Speicherverschwendung ist.

von Jörg Wunsch (Gast)


Lesenswert?

Du müßtest den Linkerscript ändern.  Standardmäßig wird progmem.data
vor den restlichen Befehlen plaziert, da für deren Zugriffe eine 64 KB
Grenze gilt (auf dem ATmega128).

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.