Forum: Compiler & IDEs Daten im FLASH an Addressen > 0xFFFF explizit ablegen


von Hagen R. (hagen)


Lesenswert?

Hi Leute,

wie sage ich dem WinAVR GCC das er große Daten im FLASH an Adressen 
größer 0xFFFF ablegen soll ?

Logischerweise bezieht sich diese Frage auf AVRs mit mehr als 64Kb an 
FLASH.
Ziel ist es zb. einen Bitmap-Datentyp zu deklarieren der sicherstellt 
das dessen Daten in den oberen 64Kb des FLASHs landen. Das vereinfacht 
dann alle Zugriffe in meinen Routinen auf diese Daten da ich nur 
einmalig in zb. mein Bitmap Zeichenroutine das RAMPZ Register laden muß.

Ich bin nämlich jetzt an eine Grenze gestoßen in denen teilweise meine 
Fonts und Bitmaps im ganzen FLASH verteilt sind. Da meine bisherigen 
FLASH Zugriffe nur mit 16Bit Zeigern arbeiten, und ich eben nicht mit 
vollen 32Bit Zeigern aus Performancegründen arbeiten möchte, wäre eine 
Untergliederung des FLASHs nach Datentyp "Bitmap" und "Font", die dann 
im oberen Teil des FLASHs gespeichert wären sehr sinnvoll.

Ideal wäre es wenn ich dem Linker sagen könnte das er diese Daten im 
FLASH entgegen der Konvention nicht von "unten nach oben" anordnet, 
sondern beginnend am FLASH Ende in Richtung Addresse 0x00000.

Gruß Hagen

von Hagen R. (hagen)


Lesenswert?

sorry noch ein Detail hintendran ;)

Es würde eventuell auch schon reichen das ich dem Linker mitteilen kann 
das er zb. einen Font oder eine Bitmap nicht gerade auf der Grenze im 
FLASH an Addresse 0x10000 linkt. D.h. es wäre egal ob er diese Daten in 
den unteren oder oberen 64Kb speichert, hauptsache dann an einem Stück 
entweder in den unteren oder oberen 64Kb.

Gruß Hagen

von Peter S. (psavr)


Lesenswert?

Du kanst eigene Sections definieren und dem Linker sagen, an welcher 
Adresse Du sie haben möchtest.

Beispiel:
1
#include <avr/pgmspace.h>
2
3
//--------------------------------------------------
4
// Linker-Option to link MyMemSection to 0x00010000
5
// -Wl,--section-start,.My_Mem_Section=0x00010000
6
//--------------------------------------------------
7
8
#define MyMemSection __attribute__((section(".My_Mem_Section")))
9
10
const unsigned char my_data[] MyMemSection =
11
{
12
  0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61, 0x00, 0x0c,
13
  0x2e, 0x6e, 0x63, 0x64, 0x00, 0x62, 0x00, 0x0a, 0x33
14
};

von Hagen R. (hagen)


Lesenswert?

Hm, ich brauche da echt Hilfe. Folgende Fakten:

1.) definiert man im MakrFile für den Linker eine neue Section ab 
Addresse 0x10000 zb. und legt darin seine Daten ab, dann kann es 
vorkommen das sich die normale .text Section mit dieser überlagert. Das 
führt zu einem Linkerfehler. Deswegen dachte ich....

2.) versucht man eine der ".finiN" Sections zu vergewaltigen und 
definiert diese im MakeFile an Addresse 0x10000 um, dann hat das 
keinerlei Wirkung. Idee dabei war das diese Sections alles Subsections 
vom .text sind und somit der Linker eventuell ausgetrickst wird und 
keine Fehler mehr meldet bei Überschneidungen. Ergo die Frage ist:

Wie deklariert man eine Section die innerhalb des .text Segementes zum 
liegen kommmt aber an einer festen Addresse, zb. 0x10000 beginnt ?

Weiter: WinAVR GCC versteht nur 16 Bit Zeiger. Soviel habe ich durch die 
Docus und bei AVRFreaks gelernt. Nun stellt sich die Frage wie man die 
Daten im FLASH > 0x10000 real addressieren kann ?

Irgendwie erscheint es mir so als ob WinAVR GCC Daten im FLASH an 
Addressen > 64Kb garnicht unterstützt. Klar in pgmspace.h findet man die 
??_far() Makros nur was nutzen einem die wenn man nicht seine Daten im 
FLASH referenzieren kann ?

Ich weis das man dies mit zusätzlichen ASM inlines/Makros zu lösen 
bekommt, das wäre aber auch nur ein Trick. Und viel wichtiger ist es das 
man mit diesem Trick keine untereinander verlinkten Menustrukturen im 
FLASH aufbauen kann.

Am wichtigsten wäre mir erstmal die Frage wie man eine Section 
definieren kann die innerhalb der .Text Section zum liegen kommt und 
eine feste Startaddresse besitzt, zu beantworten.
Beim Rest muß ich halt damit leben das meine Bitmap Zeichenroutine die 
Bitmapdaten immer in der zweiten 64Kb Page erwartet.

Gruß Hagen

von Hagen R. (hagen)


Lesenswert?

@Peter,

ja das wusste ich schon, Problem dabei ist das sich eben die .text 
Section, wenn sie wächst, mit dieser selbst deklarierten Section 
überschneidet. Das führt zu einem Linker Fehler, logisch. Ich suche nun 
nach einer Möglichkeit

a.) diese Section als Section innerhalb der .Text Section zu deklarieren
b.) diese Section, wenn die .Text Section größer wird, autom. nach oben 
zu verschieben

eines von beiden würde reichen. Ich habs jetzt erstmal manuell gemacht. 
Dh. sobald .text die 64Kb Grenze überschreitet muß ich halt das MakeFile 
anpasssen. Ist aber nicht gerade eine Lösung für ein Projekt das später 
mal andere Programmierer nutzen sollen.

Gruß hagen

von Peter S. (psavr)


Lesenswert?

Ohne ein Makro welcher Dir einen Progmem Pointer >16Bit liefert, wird es 
nicht gehen. aber das sollte ja kein Problem sein:
1
//----------------------------------------------------------
2
// macro to access data defined in FLASH above 64kB
3
//----------------------------------------------------------
4
#define FAR(var)                            \
5
({                                          \
6
  uint_farptr_t tmp;                        \
7
                                            \
8
    __asm__ __volatile__(                   \
9
                                            \
10
            "ldi    %A0, lo8(%1)"   "\n\t"  \
11
            "ldi    %B0, hi8(%1)"   "\n\t"  \
12
            "ldi    %C0, hh8(%1)"   "\n\t"  \
13
            "clr    %D0"            "\n\t"  \
14
        :                                   \
15
            "=d" (tmp)                      \
16
        :                                   \
17
            "p"  (&(var))                   \
18
    );                                      \
19
    tmp;                                    \
20
})
21
//----------------------------------------------------------

Wie man eine neue Section einfach an die Letzte hängt, weiss ich auch 
nicht, geht aber bestimmt irgendwie...

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.