eeprom_busy_wait(); löst Warning aus

Gast #3101195
Lesenswert?

Hi.

Nutze das Atmel Studio 6.1 .
Bei jedem "eeprom_busy_wait();" bekomme ich eine Warning mehr 
dargestellt.
Die Warning heißen immer so:
>Warning  20  3485 : cast to 'volatile uint8_t *' (aka 'volatile unsigned char *')
>from smaller integer type 'uint16_t' (aka 'unsigned short')"

Kann sich wer vorstellen was das Teil von mir möchte?

Toni
#3101200
Lesenswert?

Da wird eine Funktion aufgerufen, die eine Pointer als Argument haben 
möchte. Du stopfst aber einen unsigned integer rein.
Steht doch in der Fehlermeldung!

Auch wenn der Zahlenwert stimmt, der Datentyp stimmt nicht überein. Ein 
Integer ist nun mal keine Adresse.

20 Sekunden sind ja auch was anderes als 20 Meter in der Physik.
#3101210
Lesenswert?

Rene H. schrieb:
> Karl Heinz Buchegger schrieb:
>> Da wird eine Funktion aufgerufen, die eine Pointer als Argument haben
>> möchte. Du stopfst aber einen unsigned integer rein.
>> Steht doch in der Fehlermeldung!
>
> Hmm... Denke ich nicht,

Das ist das was in der Fehlermeldung steht.
Mehr kann man sagen, wenn du deinen Code bzw. die Definition von 
eeprom_busy_wait zeigen würdest bzw. etwas von der Umgebung des Codes. 
Und wenn geht inklusive der Datentypen von beteiligten Variablen.

Wir sind ja keine Telepathen.
Gast #3101213
Lesenswert?

@Karl Heinz: Ja, das dachte ich mir auch. Aber wo kommt das her? Die 
"Funktion" ist eigentlich ein define aus der eeprom.h die mit geliefert 
wird.

@Rene: Das ist die ganze Zeile :)
Rückgabewert gibt es nicht - ist ein Define aus der eeprom.h

EEprom.h
1
/** \def eeprom_busy_wait
2
    \ingroup avr_eeprom
3
    Loops until the eeprom is no longer busy.
4
    \returns Nothing.
5
 */    
6
#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
1
# define eeprom_is_ready()  bit_is_clear (EECR, EEPE)
#3101223
Lesenswert?

Toni schrieb:

> EEprom.h
>
1
/** \def eeprom_busy_wait
2
>     \ingroup avr_eeprom
3
>     Loops until the eeprom is no longer busy.
4
>     \returns Nothing.
5
>  */
6
> #define eeprom_busy_wait() do {} while (!eeprom_is_ready())
>
>
1
# define eeprom_is_ready()  bit_is_clear (EECR, EEPE)

Und weiter gehts.
Wie ist
   bit_is_clear
definiert?
Wie sind EECR bzw EEPE definiert?


Nur weil das Systemheader sind, bedeutet das ja nicht, dass da nicht wer 
geschlampt haben könnte.
Gast #3101225
Lesenswert?

In dieser Define Orgie ohne das File zu haben sich zurecht zufinden ist 
unmöglich. Ich denke ein cast vorne sollte das lösen.

Ansonsten:

Var a) eeprom.h studieren
Var b) cpp output anschauen

Ich habe meinen Rechner schon aus, sonst würde ich nach sehen (ich tippe 
hier auf einem Tablet :-).

Grüsse,
R.
Gast #3101232
Lesenswert?

"bit_is_clear" hat gar keine Farbgebung und bei Referenzsuche kommt das:
>Find References is not available because the symbol is unrecognized.

Kömisch kömisch - ich suche weiter

Die anderen beiden passen:
1
#define EECR _SFR_IO8(0x1F)
2
#define EEPE 1
Gast #3101233
Lesenswert?

Karl Heinz Buchegger schrieb:
> Rene H. schrieb:
>> In dieser Define Orgie ohne das File zu haben sich zurecht zufinden ist
>> unmöglich.
>
> :-)
>
> Ich schätze mal, dass bei EECR der Cast auf volatile uint8_t* vergessen
> wurde.
>
> Aber: das kann man rauskriegen :-)

Das was man online schon zusehen bekommt ist ein Desaster, ich will 
nicht wissen wie das auf meinem Rechner dann aussieht :-)

Schätze ich auch. Nur bin ich mir immer noch nicht sicher das der return 
da void sein soll. Das letzte Makro wurde wohl gefunden, aber die 
Deklaration der eigentlichen Funktion ist irgendwo vergraben.

Ich hasse Makros mit Funktionaliät,

Grüsse,
R.
#3101235
Lesenswert?

Toni schrieb:
> "bit_is_clear" hat gar keine Farbgebung und bei Referenzsuche kommt das:
>>Find References is not available because the symbol is unrecognized.

Wir wahrscheinlich ein Makro sein.

> Kömisch kömisch - ich suche weiter
>
> Die anderen beiden passen:
>
1
#define EECR _SFR_IO8(0x1F)
2
> #define EEPE 1

Ok.
SFR_IO8 ?

Es führt eines zum anderen. In irgendeinem File müssen die Dinger 
definiert sein. Solange bis du bei den C-Schlüsselwörtern angelangt 
bist.
Gast #3101238
Lesenswert?

Okay, also im sfr_defs.h ist es her:
1
/** \def bit_is_clear
2
    \ingroup avr_sfr
3

4
    \code #include <avr/io.h>\endcode
5

6
    Test whether bit \c bit in IO register \c sfr is clear. 
7
    This will return non-zero if the bit is clear, and a 0
8
    if the bit is set. */
9

10
#define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))

verrückt
Gast #3101239
Lesenswert?

Toni schrieb:
> "bit_is_clear" hat gar keine Farbgebung und bei Referenzsuche kommt das:
>>Find References is not available because the symbol is unrecognized.
>
> Kömisch kömisch - ich suche weiter
>
> Die anderen beiden passen:#define EECR _SFR_IO8(0x1F)
> #define EEPE 1

Mach mal ein grosses grep auf _SFR_IO8, da dürfte der Wurm sein ( wenn 
das nicht ein weiteres define sein sollte).

Das erinnert mich irgendwie an ein Bild von Escher :-).

Grüsse,
R.
Gast #3101259
Lesenswert?

Wenn es eine einzige Warnung wäre :)
Es sind bisher 31 Stellen bemeckert worden - Halt an jeder Stelle wo ich 
etwas ins EEprom lese oder schreibe.

Karl-Heinz, hast Du noch eine gute Idee dafür?
__SFR_OFFSET ist ja nun kein Pointer-Datentyp sondern wiedermal nur ein 
Define.
Ich weiß zwar nicht warum es so ein Datentyp sein sollte, aber hier 
kennst du dich besser aus.
#3101260
Lesenswert?

Toni schrieb:
>
1
#ifndef __SFR_OFFSET
2
> #  if __AVR_ARCH__ >= 100
3
> #    define __SFR_OFFSET 0x00
4
> #  else
5
> #    define __SFR_OFFSET 0x20
6
> #  endif
7
> #endif
>
> Jetzt bin ich aber in den Eingeweiden ;)

Jau. Und du bist fast durch :-)
(Ist doch auch mal interessant, in den Eingeweiden zu stöbern)

Das hier
_SFR_BYTE
fehlt noch.

PS: Bis jetzt ist noch nirgends ein Pointer Datentyp vorgekommen

Das hier

#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)

ist bis jetzt ein reiner Integer.
Wenn also _SFR_BYTE in

#define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))

da nicht noch einen Cast einführt (und nicht nur eine Dereferenzierung), 
dann hat der Compiler recht.
(Gut, das war nicht weiter verwunderlich. Der Compiler hat immer Recht. 
Selbst wenn er mal nicht recht haben sollte)
#3101266
Lesenswert?

Aber warum meckert der gcc überhaupt bei Funktionen, die mitgeliefert 
wurden und bei anderen ohne Warnungen akzeptiert werden.
Kannst du dein komplettes Projekt mal uppen (soweit bereinigt, das nur 
noch das drinnen steht, was den fehler verursacht)
Kannst du das ganze mal mit einem neuen Projekt testen

Was noch sein könnte, das der debugger die falsche Zeile anzeigt. hab 
ich auch einmal gehabt, keine ahnung waru das so war.
Zeig doch mal bitte einen ausschnitt von mindestens 20 Zeilen um ein 
eeprom_busy_wait() herum
#3101267
Lesenswert?

Toni schrieb:

> Karl-Heinz, hast Du noch eine gute Idee dafür?
> __SFR_OFFSET ist ja nun kein Pointer-Datentyp sondern wiedermal nur ein
> Define.

Ne. ne __SFR_OFFSET ist ein Integer.
__SFR_OFFSET wird entweder durch 0x00 oder durch 0x20 ersetzt. Ist für 
uns jetzt eigentlich egal, welcher genau, denn beides sind ja Integer 
(unsigned int um genau zu sein).

> Ich weiß zwar nicht warum es so ein Datentyp sein sollte, aber hier
> kennst du dich besser aus.

Na ja. Irgenwann muss ja mal aufs Register zugegriffen werden. Der ganze 
Kleinkram dient ja lezten Endes nur dazu, die Adresse des Registers 
festzulegen. Wenn man dann die ganze Makros wieder rückeinsetzt, dann 
kommt kam mit allem Pi-Pa-Po drauf, dass dein ursprüngliches

   eeprom_busy_wait();

durch die ganzen Makros zu

   do {
   } ( while (*(0x1F + 0x20) & 1 );

expandiert. Oder, wenn man den Wert in der Klammer noch ausrechnet, zu

   do {
   } ( while (*0x3F & 1 ) );

0x3F ist aber kein Pointer datentyp. Da sollte eigentlich stehen

   do {
   } ( while (*((volatile uint8_t*)0x3F) & 1 );

dann wärs richtig. Wenn jetzt in __SFR_BYTE nicht noch der Cast auf 
einen Pointer steht, dann fehlt der.
Gast #3101269
Lesenswert?

1
_SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))
2

3
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
4

5
#define _SFR_ADDR(sfr) _SFR_MEM_ADDR(sfr)
6
#define _SFR_MEM_ADDR(sfr) ((uint16_t) &(sfr))

..Tadaa, Pointer gefunden
Ja, ist schon mal interessant.
Aber das muss doch schon bei mehr Leuten passiert sein.

Jetzt hab ich plötzlich ein Error :(
Er behauptet das die eben angeklickte sfr_defs.h die inttypes.h nicht 
includieren kann -> File not found.

Ist aber unsinn da ich die selbst in .c Files includiere und hier kein 
Fehler bekomme.

Woah, was eine Nacht :)
#3101280
Lesenswert?

Lass uns das alles mal Rückeinsetzen
Ausgangspunkt war

#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
# define eeprom_is_ready()  bit_is_clear (EECR, EEPE)

Soweit so gut

EECR   war  _SFR_IO8(0x1F)
EEPE   wa 1

d.h.
bit_is_clear (EECR, EEPE)
expandiert zu

bit_is_clear( SFR_IO8(0x1F), 1)

bit_is_clear war
#define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))

damit wird das zu

(!(_SFR_BYTE(SFR_IO8(0x1F)) & _BV(1)))

_SFR_BYTE war
_SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))

bedeutet für uns
(!(_MMIO_BYTE(_SFR_ADDR(SFR_IO8(0x1F)))) & _BV(1)))

_SFR_ADDR war
#define _SFR_ADDR(sfr) _SFR_MEM_ADDR(sfr)

damit expandiert das zu
(!(_MMIO_BYTE(_SFR_MEM_ADDR(SFR_IO8(0x1F)))) & _BV(1)))

_SFR_MEM_ADDR ersetzt sich durch
#define _SFR_MEM_ADDR(sfr) ((uint16_t) &(sfr))

Hier eingesetzt, ergibt das dann
(!(_MMIO_BYTE((uint16_t)&(SFR_IO8(0x1F)))) & _BV(1)))

SFR_IO8 war
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
und für __SFR_OFFSET nehm ich einfch mal den #define 0x20 an

das eingesetzt ergibt
(!(_MMIO_BYTE((uint16_t)&(0x1F+0x20)) & _BV(1)))

Was jetzt durch den Adressoperator sowieso schon mal gefährlich ist. 
Schlimmer aber, wird das Ergebnis nach einem uint16_t gecastet.

Dieser uint16_t wiederrum ist ja leztzten Endes das, was ins Makro
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
reingeht, in Form des mem_addr.

Und da drinn wird mem_addr zum Pointer umgecastet.

Was jetzt interessant ist, ist die Tatsache, dass der Compiler meint:

> cast to 'volatile uint8_t *' (aka 'volatile unsigned char *')
> from smaller integer type 'uint16_t'

Das dieser Cast passiert, das können wir nachvollziehen. Interessant 
ist, das der Compiler davon spricht, dass der uint16_t 'smaller' als ein 
Pointer Datentyp ist. Etwas, von dem wir wissen, dass es auf einem 
AVR-Mega nicht stimmt. Ein uint16_t hat 16 Bit und ein Pointer hat auch 
16 Bit. D.h. der ist nicht smaller.


Für welchen µC programmierst du?
Ist das ein 32-Bit µC?
#3101282
Lesenswert?

Toni schrieb:
> Ihr sprecht in Rätseln :)

Einfach alle Makros rückeinsetzen :-)
Alle Textersetzungen so lange auflösen, bis nur noch C-Schlüsselwörter 
vorliegen.

> Warum lassen sich meine anderen Projekte denn kompilieren ohne Warnings?
> Natürlich mit EEprom drin.

Hast du ev. den falschen µC im Projekt eingestellt?
Irgendeinen 32-Bit µC?
Denn für den würde in der Tat gelten, dass ein uint16_t von der 
Bitanzahl her kleiner ist als ein Pointer.
Gast #3101286
Lesenswert?

Karl Heinz Buchegger schrieb:
> Oha!
>
>> #define _SFR_MEM_ADDR(sfr) ((uint16_t) &(sfr))
>
> Da hat aber wer geschlampt.

Toni schrieb:
> Ihr sprecht in Rätseln :)
>
> Warum lassen sich meine anderen Projekte denn kompilieren ohne Warnings?
> Natürlich mit EEprom drin.

Der Cast von uint16_t auf ein eine Adresse (ampersand auf sfr)  bewirkt 
die Warnung.

Weshalb Deine anderen Projekte da durchgehen kann man nicht wissen, da 
man den Code nicht kennt).

Aber wie Karl Hein schon sagte, der Compiler hat immer recht!

Grüsse,
R.

der jetzt pennen geht ....
#3101289
Lesenswert?

Toni schrieb:
> #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)

Die Zeile ist nicht OK. In meiner sfr_defs.h (von Atmel Studio 6.1) 
lautet sie:
1
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

Wundert mich, dass an Deinem Code überhaupt was funktioniert, da ja bei 
jedem Registerzugriff die Derefenzierung fehlen muss?!
Gast #3101293
Lesenswert?

Was zum Teufel Fabian.
Wieso sieht das bei dir denn so anders aus?
1
#define _SFR_MEM8(mem_addr) (mem_addr)
2
#define _SFR_MEM16(mem_addr) (mem_addr)
3
#define _SFR_MEM32(mem_addr) (mem_addr)
4
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
5
#define _SFR_IO16(io_addr) ((io_addr) + __SFR_OFFSET)
6

7
#define _SFR_IO_ADDR(sfr) ((sfr) - __SFR_OFFSET)

Datei liegt bei mir hier:
\programme\atmel\atmel toolchain\avr8 
gcc\native\3.4.2.876\avr8-gnu-toolchain\avr\include\avr
#3101295
Lesenswert?

Fabian O. schrieb:
> Toni schrieb:
>> #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
>
> Die Zeile ist nicht OK. In meiner sfr_defs.h (von Atmel Studio 6.1)
> lautet sie:
>
1
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
>

Warte mal.
Da gibts mehrere 'Define-Pfade'
Ja nachdem ob
_SFR_ASM_COMPAT
gesetzt ist, bzw. ob es ein #define für _ASSEMBLER_ gibt.

Toni. Klingelt da bei dir irgendwas?
Hast du Assembler im Projekt?
Gast #3101300
Lesenswert?

So Mädels, nu muß ich aber wirklich mal schlafen gehen.
Evtl. kann Fabian mal den Pfad in den Properties der .h anschauen und 
mit meinem Pfad vergleichen.

Melde mich morgen bzw. später nochmal.

Cu!
Toni
#3101303
Lesenswert?

Dort findest du zb auch die bereits angesprochene Option -E

Unter 'Preprocessor' mach mal einen Haken bei 'Preprocess only' rein.

Ein simples
1
#include <avr/io.h>
2
#include <avr/eeprom.h>
3

4
int main(void)
5
{
6
    while(1)
7
    {
8
      eeprom_busy_wait();
9
      PORTB |= 0x01;
10
      PORTB = 0x00;
11
    }
12
}

compiliert dann bei mir (Vorgeplänkel im outputfile *.o weggelassen) zu
1
int main(void)
2
{
3
    while(1)
4
    {
5
      do {} while (!(!((*(volatile uint8_t *)(((uint16_t) &((*(volatile uint8_t *)((0x1F) + 0x20)))))) & (1 << (1)))));
6
      (*(volatile uint8_t *)((0x05) + 0x20)) |= 0x01;
7
      (*(volatile uint8_t *)((0x05) + 0x20)) = 0x00;
8
    }
9
}

Der uint16_t da mitten drinn stört mich nach wie vor. Aber durch die 
Bitgleichheit von uint16_t und uint8_t* sollte er keine Rolle spielen.

Irgendwas stimmt da bei deinen Einstellungen nicht.
Gast #3101304
Lesenswert?

-funsigned-char -funsigned-bitfields -O1 -ffunction-sections 
-fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega164a -c -std=gnu99 -MD 
-MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"

Der 164 ist also drin.
#3101305
Lesenswert?

Gerade nochmal geschaut: In der Datei gibt es verschiedene Definitionen, 
je nachdem ob man für Assembler oder C kompiliert. Könnte also wirklich 
sein, dass die falsche Definition verwendet wird.

Edit: Hab den Post von Karl-Heinz übersehen, da stehts ja schon ...
Gast #3101308
Lesenswert?

Warning kommt auch bei dem Mini-Code.

Nur Preprocessor kommt wieder die schon oben gehabte Error-Meldung:
>Error2  ld returned 1 exit status   collect2.exe   0  0  GccApplication1

Ich glaube das Studio ist matschig.
Kann ich denn den GCC einzeln nachinstallieren?

ps. "Gehabte" -> Schlafenszeit, grins
Gast #3102852
Lesenswert?

Nach Neuinstallation ist der Fehler verflogen.
Koomische Sache wars trotzdem...

Preprozessor aus schalten kann ich ohne den oben erwähnten Fehler aber 
immer noch nicht.

Werde das Programm jetzt mal weiter stricken.

Grüße Toni

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren