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
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.
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.