_delay_ms geht nicht obwohl richtig verwendet

OP #2342944
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
Moderator Persönliche Seite #2343031
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).
Gast #2343366
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
Moderator Persönliche Seite #2343489
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. :-/
Gast #2344864
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.
Gast #2344866
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!
Moderator Persönliche Seite #2345026
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.
Persönliche Seite #2347834
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.
Moderator Persönliche Seite #2347962
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.
Persönliche Seite #2347976
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.

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