mikrocontroller.net

Forum: Compiler & IDEs Probleme mit Statemachine


Autor: Micha (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche auf einem ATtiny45 den angehängten Code zu implementieren. 
Leider noch ohne Erfolg. Wenn ich den Code im Simulator debugge, springt 
er immer von State 0 in State 5. Ich hab glaub ich schon ne 
Denkblockade. Seht ihr auf Anhieb, wieso nicht erst in State1 gesprungen 
wird?

Vielen Dank und Grüße,
 Micha

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> void TIMER1_Stop()
> {
>   TCCR1 &= 0xF0;
>
>   // Schalte Staemachine weiter
>   actState++; // schalten auf State2 oder State6 weiter
> }

Du manipulierst den Status in Userprogramm (main) und im Timer! Dein 
Timer und deine Statemachine in main laufen aber nebenläufig 
("gleichzeitig") und anders als du denkst. Überdenke dein Programmdesign 
noch mal.

Ich bin ehrlich gesagt zu faul, das Programmdesign aus dem Code 
rauszupfriemeln. Wenn du aber eine Beschreibung oder eine Zeichnung 
anhängst, schaue ich mir die Logik an.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir fällt auf, daß hier bei einigen Variablen das volatile fehlt.

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:
> Wenn ich den Code im Simulator debugge, springt
> er immer von State 0 in State 5. Ich hab glaub ich schon ne
> Denkblockade. Seht ihr auf Anhieb, wieso nicht erst in State1 gesprungen
> wird?

Der Optimizer des Compilers ist schlauer als du denkst, er erkennt, dass 
der Code für State 1 und State 5 komplett identisch ist, und fasst die 
beiden Fälle im generierten Code zusammen. Die Debuginfos/der Debugger 
können das nicht darstellen, sondern zeigen dir bei der Ausführung dann 
einen der beiden Fälle im C-Code an.

Andreas

PS: Die Sache mit volatile gilt natürlich trotzdem, so wie der Compiler 
arbeitet wird deine Hauptschleife von der Änderung von actState im 
Interrupt nie irgendwas mitbekommen. Die Variable wird lokal in einem 
Register gehalten, und nicht mehr aus dem Arbeitsspeicher geladen, 
solange die Schleife läuft.

PS2: Generell gilt, dass beim Singlesteppen von stark optimiertem Code 
die dollsten Dinge passieren können, beispielsweise dass Code scheinbar 
übersprungen wird, oder die Ausführung sich schonmal rückwärts zu 
bewegen scheint.

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Du manipulierst den Status in Userprogramm (main) und im Timer! Dein
> Timer und deine Statemachine in main laufen aber nebenläufig
> ("gleichzeitig") und anders als du denkst. Überdenke dein Programmdesign
> noch mal.

Das der Compliler zusammenfasst hätte ich gar nicht gedacht. Danke für 
den Hinweis.
Wie kann man denn neben dem volatile noch Daten zwischen einer 
Interruptroutine und dem sequentiellen Programm austauschen?

ps. Der Timer ist nur in 2 States (wahrscheinlich nach dem kompilieren 
nur in einem) aktiv.

Danke & Grüße

Autor: manoh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:
> Wie kann man denn neben dem volatile noch Daten zwischen einer
> Interruptroutine und dem sequentiellen Programm austauschen?

Such mal nach "volatile" im Forum, da wird erklärt was Schlüsselwort 
volatile bedeutet...

actState=1;
 sinnvoll benannte enums würden das Lesen vereinfachen und sie helfen 
auch Leichtsinnsfehler zu verhindern.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:

> Wie kann man denn neben dem volatile noch Daten zwischen einer
> Interruptroutine und dem sequentiellen Programm austauschen?

Was paßt dir denn an volatile nicht?

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab schon vorhin mal danach gesucht. Bei Wikipedia hab ich gefunden, 
dass der Compiler die volatile Variablen nicht optimieren soll.
Also macht ihr den Austausch zwischen einer ISR und dem Hauptprogramm 
nur über volatile-Variablen?

Danke & Grüße,
 Micha

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Was paßt dir denn an volatile nicht?

Ah ok. Gut danke. Ich hab es grad mal so probiert. Wollte mein Wissen 
nur erweitern und dachte es gibt noch andere Möglichkeiten.

Danke :)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha schrieb:
> Hab schon vorhin mal danach gesucht. Bei Wikipedia hab ich gefunden,
> dass der Compiler die volatile Variablen nicht optimieren soll.
> Also macht ihr den Austausch zwischen einer ISR und dem Hauptprogramm
> nur über volatile-Variablen?

Ja.
Eine andere Möglichkeit gibt es letzten Endes nicht. Es läuft immer 
darauf hinaus, dass in der ISR (mglw. über Umwege) eine globale Variable 
auf einen Wert gesetzt wird.

Und da das zu jedem beliebigen Zeitpunkt passieren kann, muss man dem 
Compiler mitteilen, dass er bei Optimierungen keine Annahmen über den 
Zustand dieser Variablen treffen darf.
Genau das macht 'volatile'

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Micha schrieb:
>> Hab schon vorhin mal danach gesucht. Bei Wikipedia hab ich gefunden,
>> dass der Compiler die volatile Variablen nicht optimieren soll.
>> Also macht ihr den Austausch zwischen einer ISR und dem Hauptprogramm
>> nur über volatile-Variablen?
>
> Ja.
> Eine andere Möglichkeit gibt es letzten Endes nicht.

Das ist so nicht ganz richtig. Wenn man explizize memory-barriers 
verwendet, dann braucht man keine Daten als volatile zu markieren. Das 
hat den Vorteil, dass es den Optimizer wesentlich weniger einschränkt.

Auf AVR kann man den gcc-inline-assembler memory clobber verwenden. Das 
reicht. Die CPU macht ja kein reordering von sich aus.

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.