Forum: Compiler & IDEs AVR-GCC: Wie float im Flash?


von Peter D. (peda)


Lesenswert?

Ich muß einen float aus dem Flash auslesen, leider gibt es aber nur 
pgm_read_dword und damit kriege ich folgende Warnung:

DISPLAY.C:35: warning: dereferencing type-punned pointer will break 
strict-aliasing rules

Der Code:
1
float gain_uout;
2
3
*(long*)&gain_uout = pgm_read_dword( EEP_GAIN_UOUT );

Wie kann ich die Warnung beseitigen?


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Indem du nicht versuchst zu behaupten, dass ein long das gleiche wie
ein float sei.  's ist ja auch kein Fehler, sondern eine Warnung,
dein Code ist einfach unportabel.

von SF (Gast)


Lesenswert?

So könnte es funktionieren:
1
float PROGMEM gain_flash = 1.2345;
2
float gain_ram;
3
  
4
  memcpy_P(&gain_ram, &gain_flash, sizeof(gain_ram));

von Peter D. (peda)


Lesenswert?

Jörg Wunsch wrote:

> dein Code ist einfach unportabel.

Daß, obwohl er funktioniert, irgendwo der Wurm drin ist, war mir schon 
vorher klar, sonst hätte ich die Frage ja nicht gepostet.
Ich hätte eigentlich eher nen Tip in die richtige Richtung erwartet.

Ich muß den float-Wert von einer ganz bestimmten Adresse lesen, wo ihn 
das Kalibrationsprogramm ablegt.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Ich muß den float-Wert von einer ganz bestimmten Adresse lesen, wo ihn
> das Kalibrationsprogramm ablegt.

Schon klar, dafür ist es ja ein EEPROM. ;-)

SF's Beispiel sollte es tun.  Die Beschwerde war, dass du zwei
Zeiger auf völlig unterschiedliche Typen vergewaltigst.  Wenn man
stattdessen über void * geht, ist die Sache portabel.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger wrote:
> Jörg Wunsch wrote:
>
>> dein Code ist einfach unportabel.
>
> Daß, obwohl er funktioniert, irgendwo der Wurm drin ist, war mir schon
> vorher klar, sonst hätte ich die Frage ja nicht gepostet.
> Ich hätte eigentlich eher nen Tip in die richtige Richtung erwartet.
>

Hast schon mal versucht, über ne Union zu lesen? Also ohne Casts durch 
Überlagern von long und float? Ist zwar unschon und kostet evtl n paar 
Bytres Code, aber die Warnung sollte weg sein.

Ausserdem kann man iirc die entsprechene Optimierung deaktivieren, so 
daß kein Fehler mehr entstehen kann.

...ah, schon gefunden:

Beitrag "dereferencing type-punned pointer - was ist das?"

von Tmo (Gast)


Lesenswert?

Hi,

ich erledige das mit folgendem Standardtyp (kostet keinen extra  Code 
oder Speicher):
1
typedef union
2
{
3
  u8 _a[4];
4
    s8 _sa[4];
5
  u16 _w[2];
6
    s16 _sw[2];
7
    u32 _l;
8
    s32 _sl;
9
    f32 _f;
10
    struct
11
    {
12
        u8 u8Lo;
13
        u16 u16Mid;
14
        u8 u8Hi;
15
    } _uMid;
16
    struct
17
    {
18
        s8 s8Lo;
19
        s16 s16Mid;
20
        s8 s8Hi;
21
    } _sMid;
22
} tBuffer32;

Gruss und hoffe es hilft ...

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.