Forum: Compiler & IDEs _delay_ms geht nicht obwohl richtig verwendet


von Sebastian B. (sebastian_b86)


Lesenswert?

Ich habe seit neustem ein problem mit einem code den ich das letzte mal 
vor 4 monaten angefasst habe.
beim kompilieren bekomme ich folgenden fehler:
1
avr-gcc -mmcu=atmega168 -Os -g -Wall -ffreestanding -fshort-enums -fpack-struct -std=gnu99 -Iusbdrv -I. -DF_CPU=16000000UL   -c -o receiver.o receiver.c
2
In file included from rf12.h:50:0,
3
                 from receiver.c:29:
4
/usr/lib/gcc/avr/4.5.3/../../../avr/include/util/delay.h: In function ‘main’:
5
/usr/lib/gcc/avr/4.5.3/../../../avr/include/util/delay.h:153:28: error: __builtin_avr_delay_cycles expects an integer constant.
6
/usr/lib/gcc/avr/4.5.3/../../../avr/include/util/delay.h:153:28: error: __builtin_avr_delay_cycles expects an integer constant.
7
/usr/lib/gcc/avr/4.5.3/../../../avr/include/util/delay.h:153:28: error: __builtin_avr_delay_cycles expects an integer constant.
8
make: *** [receiver.o] Fehler 1

In der Zeile steht:
1
_delay_ms(250);
 2x
sowie später nochmal
1
_delay_ms(15);

vor 4 monaten hat er kompiliert, jetzt nimmer mehr. nach meinem git hat 
sich in der zwischenzeit nichts geändert, uU jedoch die version vom 
avr-gcc

: Verschoben durch User
von Sebastian B. (sebastian_b86)


Lesenswert?

Hans schrieb im Beitrag #2342951:
> Sebastian B. schrieb:
>> vor 4 monaten hat er kompiliert, jetzt nimmer mehr. nach meinem git hat
>> sich in der zwischenzeit nichts geändert, uU jedoch die version vom
>> avr-gcc

soll mir jetzt sagen ich sollte vllt den avr-gcc downgraden? lieber wärs 
mir wenn ich wüsste wie ich _delay_ms() wieder korrekt verwende...

von Chris (Gast)


Lesenswert?

Schau' mal im header, ob DELAY_BACKWARD_COMPATIBLE erwähnt wird. Dann 
wird es wohl am einfachsten sein, das Makro vor Deinen includes zu 
definieren.

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


Lesenswert?

Chris schrieb:
> Schau' mal im header, ob DELAY_BACKWARD_COMPATIBLE erwähnt wird. Dann
> wird es wohl am einfachsten sein, das Makro vor Deinen includes zu
> definieren.

Nein, das sollte an sich nicht nötig sein.

Sebastian, irgendwie passt die Fehlermeldung nicht zur Aussage,
wie die beiden _delay_ms-Aufrufe sind, denn da stehen ja
Konstanten drin.

Kannst du mal bitte das Kommando
1
avr-gcc -mmcu=atmega168 -Os -g -Wall -std=gnu99 -Iusbdrv -I. -DF_CPU=16000000UL   -E -o receiver.i receiver.c

ausführen und die Datei receiver.i entweder hier als Anhang posten
oder aber mir zumailen (wenn du sie nicht veröffentlichen magst)?

Die ganzen -f-Optionen solltest du dir besser abgewöhnen.
-fpack-struct ist beim AVR-GCC ohnehin überflüssig, denn der AVR
benötigt keinerlei besonderes memory alignment, sodass Strukturen
ohnehin dichtestmöglich im Speicher abgelegt werden.  -fshort-enum
sollte man besser durch
1
enum { ... } __attribute__((packed)) xxx;

schreiben, weil dann sichergestellt ist, dass der Compiler alle
Instanzen der enums gleich behandelt.  (Ansonsten würdest du ein
Problem bekommen, wenn du gegen Objekte beispielsweise aus einer
Bibliothek linkst, die nicht mit dieser Option compiliert worden
sind.)  -ffreestanding sieht nur auf den ersten Blick wie eine
sinnvolle Option aus, auf den zweiten Blick verhindert sie nämlich
sämtliches "eingebautes Wissen" des Compilers über die Semantik
von Bibliotheksfunktionen, was zu einer u. U. deutlichen Pessimie-
rung des Codes führen kann.  Währed mit -fhosted (was der Default
ist) bspw. ein
1
   i = strlen("Hi there!");

in
1
   i = 9;

optimiert wird, zwingst du mit -ffreestanding den Compiler,
tatsächlich zur Laufzeit die Funktion strlen aufzurufen.  Da
der einzige Grund, warum die Leute -ffreestanding benutzen, oft
die Tatsache ist, dass der Compiler auf diese Weise ein
1
void main(void) {
2
  ...
3
}

nicht mehr warnt, wenn du stattdessen die zum hosted mode
kompatible Form
1
int main(void) {
2
3
  ...
4
  for (;;) {
5
    ...
6
  }
7
}

benutzt, generierst du trotzdem nicht mehr Code, bekommst aber
auch mit -fhosted keine Warnung mehr (auch nicht wegen des
fehlenden return, denn dem Compiler ist dann klar, dass dieses
sowieso nie erreicht würde).

von Sebastian B. (sebastian_b86)


Lesenswert?

@Jörg: Wow, ich hab die ganzen -f optionen ausm makefile rausgenommen 
und jetzt kompiliert es auch mit der neusten version vom gcc-avr.

Die hatte ich einfach mal wo übernommen, weiß gar nimmer mehr warum 
eigentlich... dann lass ich sie einfach weg :D Danke!

von Holger (Gast)


Lesenswert?

@Jörg Wunsch:
Wow! Danke für die ausführliche und informative Antwort! Das ist einer 
der wenigen Threads, die in kurzer Zeit wirklich mal was rüberbringen 
und nicht in Gezänk und gegenseitigen Beleidigungen enden...

Danke,
Holger

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


Lesenswert?

Sebastian B. schrieb:
> Wow, ich hab die ganzen -f optionen ausm makefile rausgenommen
> und jetzt kompiliert es auch mit der neusten version vom gcc-avr.

Hmm, das macht mich stutzig ... ah, na klar, die delay-Routinen
runden seit neuestem, und das machen sie natürlich mit fabs() und
ceil().  Wenn man nun -ffreestanding benutzt, werden diese aber
nicht mehr durch den Compiler aufgelöst.

Hmpf, prinzipiell sollten die natürlich auch mit -ffreestanding
benutzbar sein.  Keine Ahnung, wie man in einem Headerfile
rausfinden kann, ob diese Option aktiviert ist. :-/

von Jasch (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Sebastian B. schrieb:
>> Wow, ich hab die ganzen -f optionen ausm makefile rausgenommen
>> und jetzt kompiliert es auch mit der neusten version vom gcc-avr.
>
> Hmm, das macht mich stutzig ... ah, na klar, die delay-Routinen
> runden seit neuestem, und das machen sie natürlich mit fabs() und
> ceil().  Wenn man nun -ffreestanding benutzt, werden diese aber
> nicht mehr durch den Compiler aufgelöst.
>
> Hmpf, prinzipiell sollten die natürlich auch mit -ffreestanding
> benutzbar sein.  Keine Ahnung, wie man in einem Headerfile
> rausfinden kann, ob diese Option aktiviert ist. :-/

_STDC_HOSTED_ sollte dann 0 sein.

Das könnte aber viel Arbeit werden, laut Doku bedeutet "freestanding" 
dass die Standard-Lib nicht (vollständig) verfügbar sein muss.

Aber die AVRs haben doch üblicherweise eine Menge Std-Lib-Kram, also 
wäre -ffreestanding doch eigentlich sowieso falsch - bzw. der Benutzer 
müsste dann eben schon verstehen was er da tut.

von Jasch (Gast)


Lesenswert?

Jasch schrieb:
> Jörg Wunsch schrieb:
>> Sebastian B. schrieb:
>>> Wow, ich hab die ganzen -f optionen ausm makefile rausgenommen
>>> und jetzt kompiliert es auch mit der neusten version vom gcc-avr.
>>
>> Hmm, das macht mich stutzig ... ah, na klar, die delay-Routinen
>> runden seit neuestem, und das machen sie natürlich mit fabs() und
>> ceil().  Wenn man nun -ffreestanding benutzt, werden diese aber
>> nicht mehr durch den Compiler aufgelöst.
>>
>> Hmpf, prinzipiell sollten die natürlich auch mit -ffreestanding
>> benutzbar sein.  Keine Ahnung, wie man in einem Headerfile
>> rausfinden kann, ob diese Option aktiviert ist. :-/
>
> _STDC_HOSTED_ sollte dann 0 sein.

Das sind zwei Unterstriche vorn und hinten, verdammte Forensoftware!

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


Lesenswert?

Jasch schrieb:

>
1
__STDC_HOSTED__
 sollte dann 0 sein.

Ja, das hatte ich dann auch bemerkt.

> Das könnte aber viel Arbeit werden ...

Für <util/delay.h> würde ich wohl dann einfach automatisch
1
__DELAY_BACKWARD_COMPATIBLE__
 aktivieren.

> Aber die AVRs haben doch üblicherweise eine Menge Std-Lib-Kram, also
> wäre -ffreestanding doch eigentlich sowieso falsch - bzw. der Benutzer
> müsste dann eben schon verstehen was er da tut.

Das war ja oben schon meine Rede.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Sebastian B. schrieb:
>> Wow, ich hab die ganzen -f optionen ausm makefile rausgenommen
>> und jetzt kompiliert es auch mit der neusten version vom gcc-avr.
>
> Hmm, das macht mich stutzig ... ah, na klar, die delay-Routinen
> runden seit neuestem, und das machen sie natürlich mit fabs() und
> ceil().  Wenn man nun -ffreestanding benutzt, werden diese aber
> nicht mehr durch den Compiler aufgelöst.
>
> Hmpf, prinzipiell sollten die natürlich auch mit -ffreestanding
> benutzbar sein.  Keine Ahnung, wie man in einem Headerfile
> rausfinden kann, ob diese Option aktiviert ist. :-/

Alternative wäre, gcc etwas dichter auf die Pelle zu rücken und anstatt 
eines bittenden ceil ein forderndes __builtin_ceil zu verwenden. Ditto 
mit __builtin_abs. Hab's allerdings nicht getestet wie sich das bei 
verschiedenen O-tufen verhält; aber schlechter als lib-Funktionen, über 
die der Compiler implizites Wissen einsetzt, sind die Built-ins auch 
nicht. Intern werden die Funktionen eh dahin abgebildet falls nicht 
-fno-builtin etc. gesetzt ist.

Die Header mit __STDC_HOSTED__ aufzublasen braucht's also nicht.

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


Lesenswert?

Johann L. schrieb:
> Die Header mit __STDC_HOSTED__ aufzublasen braucht's also nicht.

Hab' ich aber schon gemacht ... schließlich wollte ich ja den Fehler
erstmal loswerden.  Fällt jetzt einfach zurück auf den alten
Algorithmus, wenn _STDC_HOSTED_ gleich 0 ist.

Es fehlt sowas wie ein <avr/intrinsic.h>, der all diese netten
vom Compiler vordefinierten Funktionen dokumentiert.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Es fehlt sowas wie ein <avr/intrinsic.h>, der all diese netten
> vom Compiler vordefinierten Funktionen dokumentiert.

Und was sollte da drin stehen?

Das einzige, was es momentan gibt, sind ein paar Target-spezifische 
Built-ins, für die man jedoch keine(n) Header braucht und für die as 
Built-in Makros gibt: 
http://gcc.gnu.org/onlinedocs/gcc/AVR-Built_002din-Functions.html

Und die anderen Built-ins sind dokumentiert in 
http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Other-Builtins.html#Other-Builtins 
für __builtin_ braucht's auch kein Header, und für Dinge aus der libc 
sind deren Header zuständig und die Compiler-Optimierungen nur eine 
"Zugabe" die nichts am Interface ändern.

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.