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
> 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.
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.
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
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...
1 | actState=1; |
sinnvoll benannte enums würden das Lesen vereinfachen und sie helfen auch Leichtsinnsfehler zu verhindern.
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?
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
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 :)
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'
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.