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
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.
Na, poste doch bitte mal die ganze Codezeile. Er mosert einen Cast an.
Wie fängst Du den return von eeprom_busy_wait() ab und wie ist der Wert
deklariert?
Grüsse,
R.
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, eeprom_busy_wait() ist void im Argument und gibt
0 oder 1 zurück.
Grüsse,
R.
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.
@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())
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.
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.
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 :-)
"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:
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.
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
>#defineEEPE1
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.
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.
Toni schrieb:> -> #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)> Sieht auch okay aus.
Nicht so schnell.
Im Moment sieht das nicht gut aus, wenn __SFR_OFFSET keinen
Pointer-Datentyp hat.
Toni schrieb:> -> #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)> Sieht auch okay aus.>> Wie komm ich an das cpp?
Mit gcc sollte das mit der Option -E sein.
Grüsse,
R.
Toni schrieb:> Jetzt bin ich aber in den Eingeweiden ;)
In der Tat :-). Jetzt bleiben Dir nur zwei Dinge über. Die Warnung
ignorieren oder Du korrigierst das auf Pointer.
Ich würde es ignorieren. ;)
Grüsse,
R.
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.
>> 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)
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
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.
..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 :)
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?
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.
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 ....
Hmm
Ich kanns nicht nachvollziehen.
Ich hab noch eine etwas ältere AVR-Studio Version 6.0 mit einer GCC
Version 4.6.2
Mega164 eingestellt ... compiliert alles sauber
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:>
>
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?
ok.
sieh dir trotzdem nochmal die Project-Properties durch.
Menü 'Project'
der letzte Punkt 'xxxx Properties'
Im Fenster ist der Reiter 'Toolchain' interessant. Geh alle
Einstellungen für den AVR/GNU C Compiler durch.
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
Toni schrieb:> Datei liegt bei mir hier:> \programme\atmel\atmel toolchain\avr8> gcc\native\3.4.2.876\avr8-gnu-toolchain\avr\include\avr
Da liegt sie bei mir auch (genau gleiche Versionsnummer). Irgendwas muss
die bei Dir zerschossen haben. Installier am besten mal Atmel Studio
bzw. die Toolchain neu.
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.
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 ...
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
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