www.mikrocontroller.net

Forum: Compiler & IDEs _delay_ms() läuft 4 Mal schneller als erwartet


Autor: Thomas Boeck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich beginne gerade mich mit AVR uz beschäftigen. In meinem ersten 
Programm wollte ich einen LED an PB5 im Viersekundentakt blinken lassen, 
d.h. 4 Sekunde an und 4 Sekunde aus. Das Programm sieht so aus:
#include <avr/io.h>
#include <util/delay.h>

int main( void )
{
    DDRB = ( 1 << PB5 );
 
    while( 1 ) {
        PORTB ^= ( 1 << PB5);
        _delay_ms(4000.0);
    }
    return 0;
}

F_CPU ist auf 8000000UL gesetzt:
avr-gcc  -mmcu=atmega328p -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT LED.o -MF dep/LED.o.d  -c  ../LED.c

Unerwarteterweise ist die LED jedoch nur ca 1 Sekunde an und aus.
Ich benutze einen ATMega 328p. Als Takt ist der interne Oszillator mit 8 
MHz konfiguriert. Folgende Fuses sind programmiert: SUT0, CKSEL3, 
CKSEL2, CKSEL0. Avrdude sagt beim Auslesen der Fuses folgendes: 
lfuse=0xe2, hfuse=0xd9, efuse=0x04.

Wenn ich
    _delay_ms(4000.0);
durch
    for(int i=0; i<4000; i++) {
        _delay_ms(1.0);
    }
ersetze ändert sich nichts am zeitlichen Verhalten.

Was mache ich falsch?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Boeck schrieb:
> lfuse=0xe2

Wenn ich nichts übersehen habe, sollte er damit mit ~8 MHz
(interner Osz.) laufen.

Sicher, daß der Wert von lfuse stimmt?
Es riecht ja irgendwie nach programmiertem CKDIV8...

Autor: Valentin Buck (nitnelav) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So etwas macht man immer mit einem Timer!
Die util/delay.h Funktionen sind als kurze Warteschleifen für 
Entprellung, LCds, ... gedacht und kein bisschen genau!!!

Mit freundlichen Grüßen,
Valentin Buck

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wenn _delay nicht stimmt, stimmt der Timer genauso wenig.

Autor: Bingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

If you are sure the AVR is running woth the correct clockfrequency.

There is a bug in the delay.h library in avr-libc-1.7.0

Are you using WinAVR2010 (it uses avr-libc-1.7.0)?
http://www.avrfreaks.net/index.php?name=PNphpBB2&f...



Maybe try this library , for a test.
http://www.avrfreaks.net/index.php?module=Freaks%2...

mfg
Bingo

Autor: Thomas Boeck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hello Bingo,

i used the actual AVR toolchain from the atmel website. This toolchain 
seems to contain the _delay_ms() bug.
#define  __HAS_DELAY_CYCLES 0
and also
#include "delay_x.h"
resovled the problem.

Thanks for the clue.

Thomas

Autor: Bingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg has released a fixed delay.h , you can use it until avr-libc-1.7.1 
is released.

http://www.avrfreaks.net/index.php?name=PNphpBB2&f...

/Bingo

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bingo schrieb:
> Jörg has released a fixed delay.h , you can use it until avr-libc-1.7.1
> is released.

Der Einfachheit halber hier nochmal als Anhang (ich glaube, die
Anhänge bei avrfreaks.net bekommt man nur zu sehen, wenn man sich
dort anmeldet).

Sorry für die vergurkte Version von delay.h in avr-libc 1.7.0, die
geht auf meine Kappe.

Autor: Jürgen Hinze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Atmel lässt die Leute da ja wirklich eiskalt auflaufen. Da gibts nämlich 
sogar heute noch die kaputte Version zum Download. Wenn ich jetzt nicht 
zufällig auf diese Seite hier getoßen wäre, hätte ich langsam angefangen 
an mir zu zweifeln. Gibts da sonst noch irgendwelche Bugs, die Atmel 
verschweigt?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, die kaputte Version des avr-libc-Quellcodes bekommst du ja auch
nach wie vor zum Download angeboten.  Release ist release, einen Bug
kann man in einem existierenden Release nicht mehr nachträglich
reparieren.

Im Rahmen von AVR Studio 5 solltest du bei Atmel eine aktuelle Version
bekommen können.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen Hinze schrieb:
> Atmel lässt die Leute da ja wirklich eiskalt auflaufen. Da gibts nämlich
> sogar heute noch die kaputte Version zum Download.

Sicher?
Kannst Du mal den Link posten?

Ein WINAVR mit avr-libc 1.7.0 existiert meines Wissens nicht.

Der letzte WINAVR - 20100110 benutzt die avr-libc 1.6.7 und die enthält 
den Bug noch nicht.

Der Bug ist also nur für Linux-er relevant, die sich ihren AVR-GCC 
selber compilieren können.


Peter

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Jürgen Hinze schrieb:
>> Atmel lässt die Leute da ja wirklich eiskalt auflaufen. Da gibts nämlich
>> sogar heute noch die kaputte Version zum Download.
>
> Sicher?
> Kannst Du mal den Link posten?

Bin zwar nicht Jürgen, hab aber den Link :)

http://www.atmel.com/dyn/resources/prod_documents/...

Auch über die Webseiten von Atmel zu finden auf der Übersichtsseite zum 
AS4 (dort aber mit Registgrierung):
AVR Toolchain Installer
(87 MB, updated 9/10)
For use with AVR Studio 4.18 SP3
http://www.atmel.com/dyn/products/tools_card.asp?t...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Bin zwar nicht Jürgen, hab aber den Link :)
>
> http://www.atmel.com/dyn/resources/prod_documents/...

Stimmt, die ist neuer als der letzte WINAVR.

Gibt es ne Möglichkeit, sich die libc-Version anzeigen zu lassen, die 
der GCC verwendet?


Peter

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Gibt es ne Möglichkeit, sich die libc-Version anzeigen zu lassen, die
> der GCC verwendet?

Bei WinAVR gibt es ein define:
_AVR_LIBC_VERSION_STRING_

Edit:
in avr/version.h

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg

* Wer defniert __HAS_DELAY_CYCLES ? Ist das built-in? Um zu erkennen,
  ob eine Version ein bestimmtes Builtin mitbringt, mach ich ein
  entsprechendes uppercase Builtin-Define. Jedenfalls schien mir das
  als Name naheliegend; für __builtin_avr_swap also __BUILTIN_AVR_SWAP.

* Funktioniert das __builtin_avr_delay_cycles auch mit -O0 zusammen?
  Das Builtin selbst funktioniert zwar, aber es verlangt eine Konstante.
  O0 faltet zwar Konstanten, aber wenn ich keine Konstante sehe, gebe
  ich in 4.7 einen Fehler aus.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> @Jörg
>
> * Wer defniert __HAS_DELAY_CYCLES ?

Der configure-Script der avr-libc.  Das hat natürlich zur Folge,
dass eine compilierte avr-libc nicht mehr portabel auf einen anderen
Compiler ist als den, mit dem sie compiliert worden ist, aber die
Einschränkung hielt ich für vertretbar, und was besseres hatte ich
nicht gefunden.

>   ob eine Version ein bestimmtes Builtin mitbringt, mach ich ein
>   entsprechendes uppercase Builtin-Define.

Hatte ich bei delay_cycles nicht gefunden.  Gut, der Patch ist
natürlich auch noch nicht drin, Anatolij mag den irgendwie nicht.

> * Funktioniert das __builtin_avr_delay_cycles auch mit -O0 zusammen?

Dachte ich zumindest.

>   Das Builtin selbst funktioniert zwar, aber es verlangt eine Konstante.
>   O0 faltet zwar Konstanten, aber wenn ich keine Konstante sehe, gebe
>   ich in 4.7 einen Fehler aus.

Ja, einen Fehler für nicht-Konstanten fände ich sowieso gut.  Die
ganzen delay-Dinger sind ja per definitionem nur für Konstanten
konzipiert, aber immer wieder kommt mal jemand daher, der das (meist
aus Unwissenheit, wer liest schon Doku?) ignoriert.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Johann L. schrieb:
>> @Jörg
>>
>> * Wer defniert __HAS_DELAY_CYCLES ?
>
> Der configure-Script der avr-libc.  Das hat natürlich zur Folge,
> dass eine compilierte avr-libc nicht mehr portabel auf einen anderen
> Compiler ist als den, mit dem sie compiliert worden ist, aber die
> Einschränkung hielt ich für vertretbar, und was besseres hatte ich
> nicht gefunden.
>
>>   ob eine Version ein bestimmtes Builtin mitbringt, mach ich ein
>>   entsprechendes uppercase Builtin-Define.
>
> Hatte ich bei delay_cycles nicht gefunden.  Gut, der Patch ist
> natürlich auch noch nicht drin, Anatolij mag den irgendwie nicht.

Den Patch hab ich nicht 1:1 übernommen.

http://gcc.gnu.org/onlinedocs/gcc/AVR-Built_002din...
http://gcc.gnu.org/viewcvs?view=revision&revision=172416

Etwas seltsam finde ich manche Builtins schon; die gingen genauso in 
inline asm. Und Arithmetik wie FMUL wäre vor allem für Maschinen ohne 
Multiplikation sinnvoll (per libgcc), wo es ein FMUL gibt, ist das 
Builtin trivial...

>> * Funktioniert das __builtin_avr_delay_cycles auch mit -O0 zusammen?
>
> Dachte ich zumindest.
>
>>   Das Builtin selbst funktioniert zwar, aber es verlangt eine Konstante.
>>   O0 faltet zwar Konstanten, aber wenn ich keine Konstante sehe, gebe
>>   ich in 4.7 einen Fehler aus.
>
> Ja, einen Fehler für nicht-Konstanten fände ich sowieso gut.  Die
> ganzen delay-Dinger sind ja per definitionem nur für Konstanten
> konzipiert, aber immer wieder kommt mal jemand daher, der das (meist
> aus Unwissenheit, wer liest schon Doku?) ignoriert.

Ich erinnere mich an Probleme bei Code wie
{
   unsigned long i = 10;
   __builtin_avr_delay_cycles (i); // oder i+4
}

oder ähnlichen einfachen Fällen, wo der Wert des Arguments zwar 
prinzipiell zur Compilezeit bekannt ist, aber das Builtin aufgrund von 
O0 keine Konstante sieht.

Das wäre ziemlich blöd, weil man den Code dann nicht einfach mal mit O0 
testen könnte. Andererseits kann ich auch nicht in eine Funktion, die 
eine Konstante erwartet, ein Register geben. Einzige Lösung wäre eine 
Bibliotheksfunktion mit variablem fuzzy delay nebst einer gcc-Warnung, 
daß diese benutzt wird.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:

> Den Patch hab ich nicht 1:1 übernommen.
>
> 
http://gcc.gnu.org/onlinedocs/gcc/AVR-Built_002din...
> http://gcc.gnu.org/viewcvs?view=revision&revision=172416

OK.  Vielleicht baue ich das nochmal um, wenn deine Version dann
eine gewisse Verbreitung erreicht hat.  Oder die Heuristik via
./configure, aber ein Überschreiben, falls _BUILTIN... dann zur
Compilezeit der Applikation existiert.

> Ich erinnere mich an Probleme bei Code wie
>
{
>    unsigned long i = 10;
>    __builtin_avr_delay_cycles (i); // oder i+4
> }
>
> oder ähnlichen einfachen Fällen, wo der Wert des Arguments zwar
> prinzipiell zur Compilezeit bekannt ist, aber das Builtin aufgrund von
> O0 keine Konstante sieht.

Ja, der ist aber eben auch nicht wirklich konstant, da beispiels-
weise der Nutzer vor dem Debugger auf die Schnapsidee kommen könnte,
i einen anderen Wert zuzuweisen.

Wie sieht es aus, wenn `i' zusätzlich noch als `const' gekennzeichnet
ist?  Unter C++ wäre es ja dann eindeutig eine Konstante, aber unter
C vermutlich nach wie vor nicht, oder?  Naja, wer in C Konstanten
braucht, muss halt nach wie vor #define benutzen, auch im 3. Jahr-
tausend. :-/

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
>> * Funktioniert das __builtin_avr_delay_cycles auch mit -O0 zusammen?
>
> Dachte ich zumindest.

Wird das __builtin_avr_delay_cycles bei -O0 überhaupt benutzt?
Aus delay.h (1.7.0)
#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__)
  extern void __builtin_avr_delay_cycles(unsigned long);
  __builtin_avr_delay_cycles(__tmp);
#else

Autor: Titan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hey leute bin schon ne ganze weile auf dieser webside am surfen, danke 
für alle beiträge hat mir sehr geholfen!!!

nun habe ich jedoch ein problem wo ich net mehr weiter weiß:


#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
   (z. B. durch Übergabe als Parameter zum Compiler innerhalb 
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
   "nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
#endif
#include <util/delay.h>
 
int main( void )
{
    DDRB = ( 1 << PB0 );        // PB0 an PORTB als Ausgang setzen
 
    while( 1 ) {                // Endlosschleife
        PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
        _delay_ms(1000);        // Eine Sekunde +/-1/10000 Sekunde warten...
                                // funktioniert nicht mit Bibliotheken vor 1.6
 
    }
    return 0;
}



bei dem beispiel aus dem GCC TUT soll die led im 1-sekunden takt blinken 
das ist bei mir etwa 4-mal langsamer statt 4-mal schneller liegt es an 
der taktfrequenz oder ist das auch so ein "bug" oder hab ich schon die 
aktuelle version von WinAVR wo _delay_ms 4-mal langsamer gemacht worden 
ist obwohl ich des net brauch?
wo bekomme ich die alte version her?
ich benutze einen Attiny2313


plz help ;)

MfG Titan

Autor: Helfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit welcher Taktfrequenz läuft dein Attiny2313 - noch Werkseinstellung 
oder hast du was geändert, wenn ja was?

Kam beim Kompilieren die Meldung "F_CPU war noch nicht definiert, wird 
nun mit 3686400 definiert"? Werkseinstellung 1 MHz und im Programm 3.7 
MHz ist fast der Faktor 4 zu schnell...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.