mikrocontroller.net

Forum: Compiler & IDEs AVR GCC Codeoptimierung selektiv ausschalten für CLKPR Zugriffe


Autor: D. E. (stb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so richtig bin ich bei der Forensuche nicht fündig geworden, deshalb mal 
hier ein ganz einfaches Problem:

Wenn man bei (neueren) AVRs wie z.B. ATtiny25 den Clock Prescaler ändern 
möchte, dann kann man das theoretisch sehr elegant mit
CLKPR = 0x80  // MCU anzeigen, daß Teilerfaktor geändert werden soll
CLKPR = 0x03  // Prescale auf "divide by 8"

Wenn man Pech hat optimiert der Compiler die erste Zuweisung weg, damit 
wird nur die 2. ausgeführt, diese wird von der MCU aber nicht umgesetzt, 
weil die erste Anweisung nicht angekommen ist.

Gibt es eine Möglichkeit den GCC anzuweisen selektiv keine Optimierung 
durchzuführen.

Grüße

STB

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du nachweisen kannst, dass der Compiler das wirklich wegoptimiert, 
dann wäre das einen Bugreport wert. Darf er nämlich nicht, wenn CLKPR 
"volatile" ist.

Autor: D. E. (stb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi !

Bei mir geht es z.Zt. ich verwende -s als Optimierung.
In anderen Forenbeiträgen hatten aber viele schon das Problem, daß die 
Einstellung mittels CLKPR "nicht geht", was auf die Wegoptimierung 
hindeuten würde.
Aus dem Zusammenhang kam die Frahe hoch ob es einen "kugelsicheren" Weg 
gibt, jedes Risiko zu vermeiden.

Grüße

STB

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wegoptimieren tut der GCC an dieser Stelle sicher nichts, da alle
Register im Header-File mit volatile deklariert sind. Möglicherweise
fügt er aber zusätzliche Befehle zwischen die beiden Zugriffe ein, so
dass ihr zeitlicher Abstand die geforderten 4 Taktzyklen überschreitet.
Das würde man im Assemblerlisting sehen. Ich kann das bei mir aber weder
mit dem GCC 4.2.4 noch mit dem 4.3.2 reproduzieren. Vielleicht postet du
mal ein kurzes Stück deines Codes.

> Aus dem Zusammenhang kam die Frahe hoch ob es einen "kugelsicheren"
> Weg gibt, jedes Risiko zu vermeiden.

Den 100% sicheren Weg gibt es nicht, da der C-Standard keine Garantien
für die zeitbeschränkte Auaführung von Code vorsieht, was man aber in
diesem Fall bräuchte. Beim GCC gäbe es immerhin noch die Möglichkeit,
die beiden Anweisungen in Inline-Assembler zu implementieren, um zu
verhindern, dass sie auseinadergerissen werden.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> In anderen Forenbeiträgen hatten aber viele schon das Problem, daß die
> Einstellung mittels CLKPR "nicht geht", was auf die Wegoptimierung
> hindeuten würde

Nochmal: die Register sind alle volatile deklariert, damit werden 
Zuweisungen auch nicht wegoptimiert.
Wenn jemand mit den obigen beiden Zeilen Probleme hat, dann deshalb, 
weil er die Optimierungen nicht eingeschaltet hat. Dann wird das 
nötige Timing nämlich nicht eingehalten.

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

Bewertung
0 lesenswert
nicht lesenswert
Genau dafür gibt's aber auch die inline-asm-Funktionen in
<avr/power.h>.  Diese sind optimierungsunabhängig.

Autor: D. E. (stb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Jörg!

Mit der Funktion:
clock_prescale_set(x) 

aus <avr/power.h> wird es kugelsicher, man muss halt nur wissen wo es 
steht :-)

@"die anderen": Mir ging es weniger darum, was der Compiler machen darf 
bzw. je nach Optimierungsstufe tut (bei mir funktioniert es ja). Ich war 
auf der Suche nach der "kugelsicheren" Lösung des Problems.

Danke nochmal an alle!

STB

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kleiner Tipp-Nachtrag:
schalte vor der Ausführung von
clock_prescale_set(x) 
die Interrupts ab.
Sonst kann es (ganz selten) passieren, dass zwischen beide Befehle ein 
IR funkt, damit ist das 4-Zyklen-Timing nicht eingehalten und der Atmel 
ignoriert den Befehl.

Dasselbe gilt übrigens auch für einige Flash-Schreibbefehle, wer z.B. in 
seinem Bootloader IRs erlaubt, sollte daran denken.

Gruß, Stefan

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan wrote:
> kleiner Tipp-Nachtrag:
> schalte vor der Ausführung von
>
> clock_prescale_set(x)
> 
> die Interrupts ab.

Das Deaktivieren der Interrupts ist in der Funktion bereits enthalten.

Autor: DerDan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal im Ernst, der Stefan hat Recht!

Man sollte es auf jeden Fall kontrollieren!
mich hat es bei dem auslesen der Fuse Byte erwischt!

diag = boot_lock_fuse_bits_get (GET_EXTENDED_FUSE_BITS);

Geht meistens aber manchmal nicht.
Interrupts sperren und schon geht es immer.

cli();
diag = boot_lock_fuse_bits_get (GET_EXTENDED_FUSE_BITS);
sei();



mfg

DerDan

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk E. wrote:

>
> CLKPR = 0x80  // MCU anzeigen, daß Teilerfaktor geändert werden soll
> CLKPR = 0x03  // Prescale auf "divide by 8"
> 
>
> Wenn man Pech hat optimiert der Compiler die erste Zuweisung weg, damit
> wird nur die 2. ausgeführt, diese wird von der MCU aber nicht umgesetzt,
> weil die erste Anweisung nicht angekommen ist.

Hast du eine Quelle dafür?

-- Quellcode, so daß es auf einem anderen Rechner nachvollzogen werden 
kann (zB. i-File)

-- Compilerversion / OS

-- avr-gcc Aufruf-Parameter

Falls er die erste Zeile trotz volatile raushaut, ist das ein Bug.

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.