www.mikrocontroller.net

Forum: Compiler & IDEs AVR-GCC: Problem mit volatile und delay loop


Autor: Chris W. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

ich glaube ein problem mit volatile in verbindung mit delay loops
(z.b. _delay_us()) im avr gcc gefunden zu haben.

der angehaengte code tut nicht das, was er meiner meinung nach tun
sollte - das delay stimmt einfach nicht immer.

mit der mit 'nicht ok' markierten zeile funktionierts nie, mit
der 'ok' markierten zeile funktionierts, wenn ich die optimierung
auf s schalte - ohne optimierung funktionierts nie...

nicht funktionieren heisst: an nen logic-analyzer angeschlossen
sieht man, dass das delay scheinbar beliebig (auf jeden fall viel
zu lang) ist...unabhaengig vom wert von val.

verwende das aktuelle WinAVR von avrfreaks...

ach ja, volatile, weil auch aus einer interrupt-routine darauf
zugegriffen wird - ich hab den code nur der uebersichtlichkeit
halber aufs notwendige reduziert.

kann das ein compiler-bug sein oder versteh ich irgendwas nicht?

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne jetzt in die Doku zu schauen - bist Du Dir sicher, dass delay_us
ein double erwartet?

Stefan

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tatsächlich: double ... nehme alles zurück ...

Stefan

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gleitkommaargumente sind nur im konstanten Kontext zugelassen, bei dem
der Compiler das wegoptimieren kann.  Ansonsten müssen die Argumente
in der Tat uint16_t sein, weil das der Datentyp ist, den die fertige
Schleife selbst nehmen will.  Nee, Moment mal, _delay_us benutzt ja
_delay_loop_1, da ist es sogar uint8_t (bzw. wird auf den reduziert).

Sorry, das müsste man wohl in der Doku noch ein wenig hervorheben, ist
mir bislang auch noch nicht untergekommen.  Kannst ja gern einen
Bugreport dafür schreiben.

Der wesentliche Sinn dieser inline-Funktionen ist die Realisierung
kurzer fester Verzögerungen, nicht ihr universeller Einsatz an
Stellen, wo ein Timer deutlich angebrachter wäre.

Übrigens: __us hat in einem Anwenderprogramm nichts verloren.
Schreibe bitte us, microseconds, micro_seconds, u_s oder was auch
immer -- aber nichts, was mit einem Unterstrich anfängt.  Du kommst
sonst über kurz oder lang in Teufels Küche.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Selbst für mehrere kurze Verzögerungen würde ich das übrigens nicht so
machen.  Du hättest dann zur Laufzeit Multiplikationen und/oder
Divisionen.  Der Sinn der _delay_us und _delay_ms Funktionen ist, dass
der Compiler diese (teuren) Operationen zur Compilezeit auflösen kann.

Besser vielleicht eine switch-Anweisung, die mehrere delay-Werte
vorgibt oder die delay-Werte in einem Array hinterlegen.

Autor: Chris W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@OldBug

die helfen mir leider nicht weiter...


@Jörg

das mit den __ ist von cut&paste uebriggeblieben...

auch wenn ich alle doubles zu uint8_t s mache passiert
dasselbe...irgendwas stimmt einfach nicht - ich muss
doch auch die variable als parameter uebergeben koennen
ohne das dann nix mehr richtig geht???

ach ja, wenn ichs mit der 'ok' zeile kompiliere ist das
file ca. 200 gross - mit der 'nicht ok' zeile ca. 900...

auch wenn man prinzipiell den timer nehmen sollte, so
sollte das aber doch auch funktionieren oder?
ein array wuerde mir nichts bringen, weil die werte
wirklich immer unterschiedlich sind.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> das mit den __ ist von cut&paste uebriggeblieben...

Dann ist der Code, von dem du kopiert hast, der Übeltäter und sollte
verbessert werden. Führende Unterstriche sind wirklich böse in C und
C++, gewöhn dir das am besten gar nicht erst an.

Hinten angehängte Unterstriche kann man eh besser lesen. ;-)

> ach ja, wenn ichs mit der 'ok' zeile kompiliere ist das
> file ca. 200 gross - mit der 'nicht ok' zeile ca. 900...
Kein Wunder, bei letzterem muss das Programm Gleitkommaarithmetik
betreiben und braucht dafür natürlich viel mehr Code.

> auch wenn ich alle doubles zu uint8_t s mache passiert
> dasselbe...irgendwas stimmt einfach nicht - ich muss
> doch auch die variable als parameter uebergeben koennen
> ohne das dann nix mehr richtig geht???

Hm, vielleicht verlangt delay_us wirklich Compile-Time-Konstanten als
Parameter, da ansonsten Divisionen und/oder Multiplikationen zur
Laufzeit ausgeführt werden müssten. </IMHO>

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hm, vielleicht verlangt delay_us wirklich Compile-Time-Konstanten
> als Parameter, da ansonsten Divisionen und/oder Multiplikationen zur
> Laufzeit ausgeführt werden müssten.

Habe eben nochmal nachgesehen: genau so ist es.  Damit vervielfacht
sich natürlich die Verzögerung heftig.  In dem Falle muss man dann
doch wieder selbst auf die low-level Funktionen _delay_loop_1 und
_delay_loop_2 zurückgreifen und die Berechnung der Zeitkonstanten
selbst vornehmen.  Allerdings würde ich auch hier jede Art von
Division zur Laufzeit vermeiden, auch im Integer-Bereich ist die für
den Anwendungsfall immer noch viel zu teuer.

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.