Hallo,
teste gerade mit Timer0 in der Arduino Umgebung (Servo bewegen). Wegen
Doppelnutzung des Timers (Stichwort delay und millis()) löse ich mich
teilweise vom Arduino Framework - die Software soll später auf einen
Tiny85 portiert werden.
Ziel ist mit dem Timer0 125µs Raster zu erzeugen; nach einer Anzahl von
n Pulsen (Übergeben in pulsWeite) wird der Pin wieder abgeschalten.
Als Nebenkriegsschauplatz habe ich nun folgenden Effekt:obwohl die
Variable pulsWeite definiert ist, wird der Wert nicht in die ISR Routine
übergeben.
Schreibe ich den Wert fest in der ISR Routine rein (statt in Variable)
funktioniert's prinzipiell
liegt das an der Art der Definition der Variable oder habe ich ein
Verständnisproblem?
Walter T. schrieb:> Lerne die Magie von "volatile"!
Magie! Danke, läuft!!
An der richtigen Stelle nachgelesen ist zu finden:
"[...]Eine Variable sollte immer dann als „volatile“ deklariert werden,
wenn ihr Wert durch ein Ereignis
beeinflusst werden kann, welches außerhalb des Codes stattfindet, in dem
sie sich befindet. Das kann z.B.
eine gleichzeitig aufgerufene Funktion sein. Im ARDUINO – die einzige
Funktion, die so etwas kann, ist
eine Interrupt-Funktion, genannt Interrupt Service Routine [..]"
(Quelle: Arduino Befehlsübersicht, A.Nagel 2020)
Tom schrieb:> "[...]Eine Variable sollte immer dann als „volatile“ deklariert werden,> wenn ihr Wert durch ein Ereignis> beeinflusst werden kann, welches außerhalb des Codes stattfindet, in dem> sie sich befindet. Das kann z.B.> eine gleichzeitig aufgerufene Funktion sein. Im ARDUINO – die einzige> Funktion, die so etwas kann, ist> eine Interrupt-Funktion, genannt Interrupt Service Routine [..]"
Wie jede Vereinfachung, so stößt auch diese irgendwann auf ihre Grenzen.
So, wie es geschrieben ist, passt es auschließlich auf die
"Ur-Arduinos", also AVR8-MCUs. Im konkreten Fall ist sowas tatsächlich
das Target, deshalb passt es hier.
Aber schon seit sehr langer Zeit gibt es auch Arduinos mit mehr
Hardware-Power. Sei es nur durch DMA oder (in etwas neuerer Zeit auch
durch Multi-Core-MCUs).
Da passt das dann schon nicht mehr. Da hat man einerseits Sachen, wo
"volatile" auch nötig wird, ohne dass eine ISR beteiligt ist,
andererseits aber auch Sachen, wo "volatile" allein noch nicht genügt.
Reine Arduidioten sind hier völlig überfordert. Das ist so und das wird
voraussichtlich auch so bleiben. Die begreifen die dahinter steckenden
Probleme schon nicht, geschweige denn das völlig abstruse
Syntax-Geschwalle von C/C++ zu deren Lösung. Mein Gott, letzteres fällt
ja sogar Leuten schwer, die mit dem Verständnis der Hardware keinerlei
Probleme haben...
C/C++ als Sprache für erwartete Nicht-Programmierer zu wählen, war wohl
sicher nicht die weiseste Wahl der Arduino-System-Erfinder...
c-hater schrieb:> Reine Arduidioten sind hier völlig überfordert.
Hallo c-hater
Was Du an fachlicher Kompetenz hast, fehlt Dir an zwischenmenschlicher.
Schade.
Stefan ⛄ F. schrieb:> c-hater schrieb:>> völlig überfordert... Mein Gott>> Überall um dich herum sind Geisterfahrer.
Nicht alle, aber doch >>99%. So z.B. der TO dieses Threads. Und die TOs
vieler anderen Threads (nicht nur dieses Forums).
Können so viele Idioten so einheitlich darstellen, dass sie Idioten
sind, ohne sich abgesprochen zu haben? Nein, können sie nicht. Diese
geordnete und statistisch überaus signifikante Sammelvorstellung wird
allein durch das Arduino-Konzept erzeugt.
Das mag dir nicht gefallen, ist aber die reine Wahrheit. Jederzeit nach
wissenschaftlichen Kriterien ermittel- und darstellbar.
c-hater schrieb:> Das mag dir nicht gefallen, ist aber die reine Wahrheit. Jederzeit nach> wissenschaftlichen Kriterien ermittel- und darstellbar.
Das hört sich ziemlich stark nach Glauben an. Hier ist die reine
Wahrheit™, Fakten™ gibts später.
foobar schrieb:> Bei 8-Bittern reicht ein volatile nicht, um Zugriffe auf> größer-8-Bit-Variablen (wie int) interruptsicher zu machen!
Auch bei 64-Bittern ist ein volatile nicht immer ausreichen, um Zugriffe
auf 8-Bit Variablen interruptsicher zu machen.
foobar schrieb:> Bei 8-Bittern reicht ein volatile nicht, um Zugriffe auf> größer-8-Bit-Variablen (wie int) interruptsicher zu machen!
Das ist vollkommen korrekt.
Tom schrieb:> Magie! Danke, läuft!!
Noch zwei Anmerkungen, Tom.
Erstens ist das digitalWrite des Arduino recht aufwendig und benötigt
selbst einige us zur Ausführung; direkte Portzugriffe dagegen brauchen
nur wenige Takte.
Und zweitens sind deine in ISR und regulärem Kontext benutzten Variablen
als int deklariert. Der Atmega328P des Arduino Nano ist aber ein 8-Bit
Controller, Zugriffe auf ein int sind also nicht atomar. Es muss daher
bei allen Schreiboperationen auf diese Variablen die potentiell mehr als
ein Byte ändern verhindert werden dass die ISR "dazwischen" ausgeführt
wird und einen seltsamen Inhalt vorfindet. volatile macht das nicht!
LG, Sebastian
Ach, lasst den c-hater mal in Ruhe...
Sein Hass macht ihn so verblendet, dass er vergisst, dass er das mit dem
Volatile auch mal lernen musste.
Zudem ist er auf dem Gebiet C++, herzerfrischend Kenntnisfrei.
Also einer der Letzten, dessen Urteil man vertrauen sollte.
EAF schrieb:> Ach, lasst den c-hater mal in Ruhe...> Sein Hass macht ihn so verblendet, dass er vergisst, dass er das mit dem> Volatile auch mal lernen musste.
Wenn es nur um ihn gehen würde, könnte ich dir zustimmen. Es gibt aber
andere Forenteilnehmer, die ernst nehmen könnten was er geschrieben hat.
foobar schrieb:> Bei 8-Bittern reicht ein volatile nicht, um Zugriffe auf> größer-8-Bit-Variablen (wie int) interruptsicher zu machen!
Das ist schon wieder so eine Sache, die typische Arduidioten nicht
verstehen. Das ist schlicht ein anderes Problem.
Das eine ist, die Konsistenz einer Variablen in der nativen
("elementaren") Größe sicher zu stellen. Dafür ist "volatile" zuständig,
kann das aber nicht immer leisten. Beim AVR8 (ohne XMega) aber kann es
das aber noch. Ist ja auch eine ziemlich primitive Architektur...
Ein anderes Problem ist, die Konsistenz eine Variablen sicher zu
stellen, die größer ist als "elementar". Das kann "volatile" alleine
nicht mal für AVR8 leisten.
Mombert H. schrieb:> Es gibt aber> andere Forenteilnehmer, die ernst nehmen könnten was er geschrieben hat.
Rein fachlich sollten die das auch tun.
Oliver
foobar schrieb:> Bei 8-Bittern reicht ein volatile nicht, um Zugriffe auf> größer-8-Bit-Variablen (wie int) interruptsicher zu machen!Mombert H. schrieb: [... interruptsicher ...]
c-hater schrieb: [... Das ist vollkommen korrekt
...]
Sebastian schrieb:> Es muss daher [...] verhindert werden dass die ISR dazwischen ausgeführt> wird
Natürlich ist es extrem unsportlich, dem TE nun auch zu sagen, wie man
das beim AVR machen kann, ohne Mutexe zu benutzen ;-)
| uint8_t a=SREG;
| cli();
| [hier die volatile Variable auswerten oder umkopieren - nicht mehr]
| SREG=a;
HTH
(re)
> Das eine ist, die Konsistenz einer Variablen in der nativen> ("elementaren") Größe sicher zu stellen. Dafür ist "volatile"> zuständig,
Nicht mal das. Volatile ist sehr vage definiert und heißt grob gesagt
nur: "Optimizer, lass deine Finger von diesen Zugriffen!".
Oliver S. schrieb:> Mombert H. schrieb:>> Es gibt aber>> andere Forenteilnehmer, die ernst nehmen könnten was er geschrieben hat.>> Rein fachlich sollten die das auch tun.>> Oliver
Zählt es als "rein fachlich" den TO als Geisterfahrer zu bezeichnen?
Gibt es eine wissenschaftlich beweisbahre reine Wahrheit, die eine
statisch signifikante Sammelvorstellung enthält, die durch das
Arduino-Konzept erzeugt wird?
> Natürlich ist es extrem unsportlich, dem TE nun auch zu sagen, wie man> das beim AVR machen kann, ohne Mutexe zu benutzen ;-)
Das wird in den von ihm gefundenen Artikeln über volatile bestimmt schon
gesagt worden sein - hat er wohl nur nicht berücksichtigt.
Btw, Interrupts sperren ist nur eine Methode ...
foobar schrieb:> Nicht mal das. Volatile ist sehr vage definiert und heißt grob gesagt> nur: "Optimizer, lass deine Finger von diesen Zugriffen!".
Nein, primär heißt das was ganz anderes.
Oliver
Oliver S. schrieb:> foobar schrieb:>> Nicht mal das. Volatile ist sehr vage definiert und heißt grob gesagt>> nur: "Optimizer, lass deine Finger von diesen Zugriffen!".> Nein, primär heißt das was ganz anderes.> Oliver
Was ist den dieses "was ganz anderes"?
Der Standard sagt:
1
An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3. Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the
2
abstract machine, except as modified by the unknown factors mentioned previously. What constitutes an access to an object that has volatile-qualified type is implementation-defined.
Ich sehe da nicht viel Platz für "was ganz anderes".
Mombert H. schrieb:> Zählt es als "rein fachlich" den TO als Geisterfahrer zu bezeichnen?
Das hat wer getan? Niemand. Der einzige, der mit dem Begriff hantiert
hat, war der gute Stefan S. Und der hat ihn nur auf mich angewandt,
nicht auf den TO oder gar die anderen Arduidioten.
Du solltest vielleicht mal lernen, Zitate korrekt zu lesen (und damit
dann auch gleich: korrekt zu zitieren)...
c-hater schrieb:> Mombert H. schrieb:>> Zählt es als "rein fachlich" den TO als Geisterfahrer zu bezeichnen?> Das hat wer getan? Niemand. Der einzige, der mit dem Begriff hantiert> hat, war der gute Stefan S. Und der hat ihn nur auf mich angewandt,> nicht auf den TO oder gar die anderen Arduidioten.> Du solltest vielleicht mal lernen, Zitate korrekt zu lesen (und damit> dann auch gleich: korrekt zu zitieren)...
Zum "korrekt" lesen: Wie soll man das lesen?
c-hater schrieb:> Stefan ⛄ F. schrieb:>> c-hater schrieb:>>> völlig überfordert... Mein Gott>> Überall um dich herum sind Geisterfahrer.> Nicht alle, aber doch >>99%. So z.B. der TO dieses Threads. Und die TOs> vieler anderen Threads (nicht nur dieses Forums).
Wenn ich es nicht so verstanden habe wie du es gemeint hast, solltest du
auch drüber nachdenken, ob du deine Meinung für andere verständlich in
Worte gefasst hast.
Zum "korrekt" zitieren: Wie zitiert man hier korrekt?
Mombert H. schrieb:> Es gibt aber andere Forenteilnehmer,> die ernst nehmen könnten was er geschrieben hat.
Wen nimmt denn Leute mit so einer Wortwahl ernst?
Oliver S. schrieb:> Nein, primär heißt das was ganz anderes.
Genau. Das heißt nix anderes als: lies' es (erneut) von der Adresse im
RAM-Space, verlaß' dich nicht auf das, was du früher mal aus derselben
Stelle des RAM-Space gelesen (und in irgendwelchen MCU-Registern
zwischengelagert) hast.
Das löst halt das Problem, das effizienter Code bevorzugt mit Werten in
MCU-Registern hantiert, weil das viel schneller geht. Die Register sind
also aus der Sicht von Hochsprachen eine Art Cache. Und haben naturgemäß
die Probleme jedes Cache: er könnte bereits ungültig sein, wenn man ihn
benutzt.
"volatile" sorgt nun dafür, das bei jedem Lesezugriff erneut die Daten
aus dem RAM-Space in den Registercache gelesen werden. Das macht den
Code langsamer, aber sorgt halt dafür, dass es den aktuellen Datenstand
benutzt, wenn dieser zwischenzeitlich durch alternative Mechanismen
geändert wurde.
c-hater schrieb:> "volatile" sorgt nun dafür, das bei jedem Lesezugriff erneut die Daten> aus dem RAM-Space in den Registercache gelesen werden.
Und umgekehrt werden alle Schreibzugriffe direkt ins RAM durchgeführt,
nicht irgendwann später wenn die Funktion/Prozedur zu ende ist.
Stefan ⛄ F. schrieb:> Und umgekehrt werden alle Schreibzugriffe direkt ins RAM durchgeführt,> nicht irgendwann später wenn die Funktion/Prozedur zu ende ist.
Stimmt. Auch das ist wichtig und essentiell.
Mein Gott, du kannst doch offensichtlich auch faktenorentiert
argumentieren. Warum machst du das nicht auch, wenn das "arduino"-Thema
Thema ist...
c-hater schrieb:> "volatile" sorgt nun dafür,
Für einen c-hater sehr gut beschrieben.
c-hater schrieb:> faktenorentiert argumentieren. Warum machst du das nicht auch, wenn das> "arduino"-Thema Thema ist
Der war nun lustig :)
Aber gut, ich bin auch einer der Arduidioten c-haters, auch wenn ich
kritisches schon mal in Assembler schreibe ...
LG, Sebastian
Sebastian schrieb:> Aber gut, ich bin auch einer der Arduidioten c-haters, auch wenn ich> kritisches schon mal in Assembler schreibe ...
Nö. Wenn du in der Lage bist, kritische Teile in Assembler zu schreiben,
bist du definitiv eben NICHT in der Zielgruppen der Arduidioten. Oder
freundlicher ausgedrückt: der "Arduino-Nutzer".
c-hater schrieb:> "volatile" sorgt nun dafür, das bei jedem Lesezugriff erneut die Daten> aus dem RAM-Space in den Registercache gelesen werden. Das macht den> Code langsamer, aber sorgt halt dafür, dass es den aktuellen Datenstand> benutzt, wenn dieser zwischenzeitlich durch alternative Mechanismen> geändert wurde.
Mit diesen paar Sätzen definierst du deutlich mehr in volatile hinein,
als der Standard tatsächlich zusichert. Im Standard kommt kein RAM-Space
und kein Registercache vor und er definiert ganz sicher nicht, was
"aktuell" ist.
Mombert H. schrieb:> und er definiert ganz sicher nicht, was> "aktuell" ist.
Ob er das definiert, darüber könnte man geteilter Meinung sein. Keine
Diskussion braucht es dagegen über die Tatsache, daß der Standard auch
und gerade im Zusammenhang mit volatile die Begriffe „actual semantics“
und „actual objects“ dem Begriff „abstract semantics“ gegenüberstellt.
„8. Example: An implementation might define a one-to-one correspondence
between abstract and actual semantics: at every sequence point, the
values of the actual objects would agree with those specified by the
abstract semantics. The keyword volatile would then be redundant.„
Oliver