Forum: Compiler & IDEs Datenstruktur in Flash auslagern


von Thorsten H. (lordvader91)


Lesenswert?

Hallo!

Ich würde gerne eine Datenstruktur vom RAM in den Flash-Speicher 
auslagern.
Das ganze sind die Daten für eine LED-Matrix.

Meine Datenstruktur besteht aus den folgenden Typen:
1
typedef union {
2
    const uint32_t const matrix[4];
3
    const uint8_t duration;   // duration * 10ms
4
} picture_t;
5
6
7
typedef struct {
8
    const picture_t const __flash * pictures;    // picture array
9
    const uint8_t pictureCnt;    // picture count in the array
10
    const uint8_t repeatCnt;         // how often is the picture array repeatet
11
} animation_t;
12
13
typedef struct {
14
    const animation_t** animations;
15
    const uint8_t animationCnt;
16
} animationSet_t;

Eine beispielhafte Initialisierung der Struktur:
1
/* alleAnAus
2
   Description:
3
     */
4
const __flash picture_t alleAnAusPictures[2] = {
5
    {{0xFFFFFF19, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}},
6
    {{0x19, 0x0, 0x0, 0x0}},
7
};
8
const __flash animation_t alleAnAus = {
9
   alleAnAusPictures,
10
    2,
11
    1
12
};

Mein Problem ist nun, dass ich nicht so recht weiß, wie ich den __flash 
Qualifier anzuwenden habe. Mit dem Code von oben funktioniert es leider 
nicht.
Der Compiler kompiliert zwar ohne Warnungen und die Daten werden auch im 
Flash abgelegt. Das Programm funktioniert dann allerdings nicht mehr.


Wäre super, wenn mit jemand auf die Sprünge helfen könnte.

Gruß
Thorsten

Edit:

Ganz vergessen: Das ganze läuft auf einem ATmega32 und wird mit avr-gcc 
Version 4.9.2 kompiliert.

: Bearbeitet durch User
von Sven S. (boldie)


Lesenswert?

Also mein PC hat keinen Flash. Was für eine Architektur + Compiler hast 
du?

: Bearbeitet durch User
von Thorsten H. (lordvader91)


Lesenswert?

Sorry, hab ich ganz vergessen. Hab den Beitrag editiert.
ATMega32 mit avr-gcc 4.9.2

von isidor (Gast)


Lesenswert?

Sven S. schrieb:
> Was für eine Architektur + Compiler hast du?

Hat er doch geschrieben, kannst nich lesen ?

von Thorsten H. (lordvader91)


Lesenswert?

isidor schrieb:
> Sven S. schrieb:
> Hat er doch geschrieben, kannst nich lesen ?

Na, aber erst im Nachhinein. ;-)

Das Problem hat sich gelöst. Ich habe vergessen für die Variablen in den 
Funktionen, die auf die Flash-Variablen zugreifen, __flash zu benutzen.
Jetzt funktioniert es.

von isidor (Gast)


Lesenswert?

Thorsten H. schrieb:
> Jetzt funktioniert es.

Kannst bitte ein Minimalbeispiel listen, es würde mich
auch interessieren.

von Thorsten H. (lordvader91)


Lesenswert?

Folgende Funktionen greifen auf die Variablen zu:
1
bool playAnimation(const __flash animation_t const * animation);
2
bool playAnimationSet(const __flash animationSet_t const * animationSet);
3
bool playPicture(const __flash picture_t const * picture);
4
uint32_t getColumn(const __flash picture_t const * picture, uint8_t col);

Dazu noch zwei globale Variablen, die auf die aktuellen Daten verweisen:
1
const __flash picture_t* currentPic = 0;
2
const __flash animation_t* currentAnimation = 0;

Dort fehlte überall das __flash.

von isidor (Gast)


Lesenswert?

Danke sehr.

Irritierend finde ich bei Typdeklarationen dass "const"
zweimal vorkommt. Hab es nicht getestet, muss das so sein?

von Thorsten H. (lordvader91)


Lesenswert?

Das erste const für die Variable, die sich nicht ändern soll und das 
zweite const für den Pointer, der auch nicht geändert werden soll.
So habe ich mir das gedacht. Korrigiert mich, wenn ich da einen 
Denkfehler habe.

von Hans (Gast)


Lesenswert?

Wenn der Zeiger (sprich die Adresse) nicht geändert werden soll, müsste 
das const rechts vom "*" stehen. Allerdings ist das bei einem 
Funktionsargument recht sinnlos, weil die Funktion ja eine Kopie des 
Zeigers bekommt. Ob sie die ändert oder nicht spielt für den Aufrufer 
keine Rolle.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Thorsten H. schrieb:
> Das erste const für die Variable, die sich nicht ändern soll und das
> zweite const für den Pointer, der auch nicht geändert werden soll.

No, die beiden const sind redundantz, d.h. eines kann weggelassen 
werden: Ob du schreibst "typ const" oder "const typ" ist Wurscht, ditto 
beliebig viele Kopien vor oder nach dem Typ.

Bei Zeigern spielt es eine Rolle, auf welcher Seite des "*" das const 
steht, aber bei deinem Code ist es an keiner Stelle ein typ*.

von Rolf M. (rmagnus)


Lesenswert?

Sven S. schrieb:
> Also mein PC hat keinen Flash.

Echt? Von wo kommt dann das BIOS?

Johann L. schrieb:
> No, die beiden const sind redundantz, d.h. eines kann weggelassen
> werden: Ob du schreibst "typ const" oder "const typ" ist Wurscht, ditto
> beliebig viele Kopien vor oder nach dem Typ.
>
> Bei Zeigern spielt es eine Rolle, auf welcher Seite des "*" das const
> steht,

Naja, allgemein ausgedrückt: Das const wirkt immer auf das, was links 
davon steht. Einzige Ausnahme ist, wenn das const selbst ganz links 
steht. Dann wirkt es auf das, was rechts steht.
Also:
1
X const *       // nicht-konstanter Zeiger auf konstantes X
2
X * const       // konstanter Zeiger auf nicht-konstantes X
3
X const * const // konstanter Zeiger auf konstantes X
4
const X *       // Sonderfall, Effekt ist wie beim ersten Beispiel
5
const X * const // wie Fall 3
6
const X const * // redundantes const, beides bezieht sich auf das X

> aber bei deinem Code ist es an keiner Stelle ein typ*.

Nicht?

Thorsten H. schrieb:
> uint32_t getColumn(const __flash picture_t const * picture, uint8_t
> col);

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.