Forum: Mikrocontroller und Digitale Elektronik Frage: Atmega >64k, PROGMEM und Pointer, AVR Studio 6


von BirgerT (Gast)


Lesenswert?

Habe in einem ATmega128 (Nibo 2) per PROGMEM Strings abgelegt, die 
insgesamt die 64k-Grenze überschreiten, weil ich testen wollte, ob meine 
Funktionszeiger noch das tun, was ich mir vorstelle, wenn der Code 
selber oberhalb der 64k liegt - und das funktioniert augenscheinlich.

Aber alle PROGMEM Daten oberhalb der 64k Grenze sind natürlich nicht 
mehr über pgm_read_byte() "erreichbar" - ok, dafür gäbe es dann 
pgm_read_byte_far(), aber..

Ich stelle mir vor, dass ich ein bestimmtes Array oberhalb der 64k 
Grenze ablege, und dann nur hier mit der "far"-Version d'rauf zugreife.

Meine Fragen:
a)
Kann ich z.Bsp. per #define bestimmen, an welche Adresse und in welcher 
Reihenfolge ich die Daten (Arrays) im Flash abgelegt haben möchte?

b)
Oder muss ich generell alle Flashleseoperationen auf farPointer 
umstellen, wenn ich über 64K komme?

c)
Wonach muss ich suchen, um eine Lösung zu finden?


Und mal ehrlich - hat es hier schon jemand geschafft, einen Maschinen 
Code (nur Funktionen) > 64k zu programmieren..?

von Bastler (Gast)


Lesenswert?

Solange PROGMEM unter 64k bleibt, reichen 16Bit. Und da (so das 
Linkerscript) erst danach mit Code aufgefüllt wird, ist nicht die 
Gesammt-FLASH-Größe wichtig. Code benutzt ja eh Wort-Pointer, also bis 
128kB reichen 16Bit. Solange du keinen 256er benutzt, bleibt's easy.

von Falk B. (falk)


Lesenswert?

@ BirgerT (Gast)

>Habe in einem ATmega128 (Nibo 2) per PROGMEM Strings abgelegt, die
>insgesamt die 64k-Grenze überschreiten, weil ich testen wollte, ob meine
>Funktionszeiger noch das tun, was ich mir vorstelle, wenn der Code
>selber oberhalb der 64k liegt - und das funktioniert augenscheinlich.

Funktionszeiger gehen bis 128kB, weil die Zeiger 16 Bit Worte 
adressieren.

>Ich stelle mir vor, dass ich ein bestimmtes Array oberhalb der 64k
>Grenze ablege, und dann nur hier mit der "far"-Version d'rauf zugreife.

Kann man machen, bringt aber wenig. Man verhaspelt sich eher mit dem 
Zugriff an verschiedenen Stellen.

>Kann ich z.Bsp. per #define bestimmen, an welche Adresse und in welcher
>Reihenfolge ich die Daten (Arrays) im Flash abgelegt haben möchte?

Nein.

>Oder muss ich generell alle Flashleseoperationen auf farPointer
>umstellen, wenn ich über 64K komme?

Nein, ist aber empfehlenswert.

>Wonach muss ich suchen, um eine Lösung zu finden?

Wofür?

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Variablenzugriff_.3E64kB

>Und mal ehrlich - hat es hier schon jemand geschafft, einen Maschinen
>Code (nur Funktionen) > 64k zu programmieren..?

Sicher, wenn gleich das auf einem kleinen 8 Bitter schon etwas 
anstrengender wird.

: Bearbeitet durch User
von BirgerT (Gast)


Lesenswert?

Bastler schrieb:
> Code benutzt ja eh Wort-Pointer, also bis
> 128kB reichen 16Bit. Solange du keinen 256er benutzt, bleibt's easy.

Das auf Wordpointer auf den Code zeigen.. war mir entfallen; ich werde 
hoffentlich an Dich denken, wenn ich meine 256er Boards ausreizen will -

Danke Bastler

Falk B. schrieb:

> Funktionszeiger gehen bis 128kB, weil die Zeiger 16 Bit Worte
> adressieren.

Ja, daran habe ich nicht mehr gedacht

>
>>Ich stelle mir vor, dass ich ein bestimmtes Array oberhalb der 64k
>>Grenze ablege, und dann nur hier mit der "far"-Version d'rauf zugreife.

>>Wonach muss ich suchen, um eine Lösung zu finden?
>
> Wofür?
>
> 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Variablenzugriff_.3E64kB
>

na dafür - Herzlichen Dank Falk für den Link auf die gesuchte Lösung

Jetzt bin ich aber gespannt, ob der Code dazwischen landet..

von BirgerT (Gast)


Lesenswert?

BirgerT schrieb:

> Jetzt bin ich aber gespannt, ob der Code dazwischen landet..

Ok - ohne genau zu wissen, was ich da jetzt abgetippt habe - das scheint 
zu funktionieren:
Die .far_section ist zwar in der .lss nicht erkennbar; es werden nur 
PROGMEM Daten und der Code angezeigt, und das "letzte Wort" hat bei mir 
derzeit die Adresse c5c0.

Die Daten an Adresse 0x10000 lassen sich aber wie beschrieben mit 
pointer + offset lesen.

Im AVR Studio 6 kann die Linkeroption in den Projekt-Properties 
[ALT]+[F7] unter "Toolchain"->"AVR/GNU Linker - Memory Settings" im 
Textfeld "FLASH Segment" hinzufügen.
Aber ich musste dort ".far_section=0x8000" eintragen, damit bei "AVR/GNU 
Linker - All Options" auch "-WL,--section-start=.far_section=0x10000" 
angezeigt wird?!

Aber was passiert, wenn der Code bis in die .far_section reinreichen 
würde..

Vielleicht kann jemand das Tutorial mit "const" ergänzen:
1
const char MyString[] FAR_SECTION = "Hier liegt mein FAR-Teststring!";
2
const char MyBmp64[]  FAR_SECTION = {0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0x00};

Also nochmal Danke an Falk und an die Autoren des Tutorials - hat 
geholfen.

von Falk B. (falk)


Lesenswert?

@ BirgerT (Gast)

>Im AVR Studio 6 kann die Linkeroption in den Projekt-Properties
>[ALT]+[F7] unter "Toolchain"->"AVR/GNU Linker - Memory Settings" im
>Textfeld "FLASH Segment" hinzufügen.
>Aber ich musste dort ".far_section=0x8000" eintragen, damit bei "AVR/GNU
>Linker - All Options" auch "-WL,--section-start=.far_section=0x10000"
>angezeigt wird?!

Mal den kleinen Hilfetext dort gelesen?

"Note that the address has been multiplied by 2 to get the byte 
address."

>Aber was passiert, wenn der Code bis in die .far_section reinreichen
>würde..

Dann wird der Linker einen Fehler erzeugen und abbrechen, denn sich 
überlappende/überfüllte Sections gehen nicht.

>Vielleicht kann jemand das Tutorial mit "const" ergänzen:

Ich war so frei.

von Stefan E. (sternst)


Lesenswert?

Falk B. schrieb:
> Funktionszeiger gehen bis 128kB, weil die Zeiger 16 Bit Worte
> adressieren.

Nö, die gehen auch darüber hinaus, weil der Linker dann Trampolines im 
unteren Teil (direkt hinter den Interrupt-Vektoren) generiert.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

BirgerT schrieb:
> .far_section
> FAR_SECTION

Geht freilich auch ohne das Rumgestochere mit Inline-Assembler, z.B. per 
__memx oder — falls die Daten in 0x10000...0x1ffff liegen — mit 
__flash1.

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.