Hallo Leute, ich implementieren momentan eine CAN lib! Zum empfangen der daten verwende ich den Interrupt, darin wird die CAN-Controller FIFO ausgelesen, und möchte das empfange frame in eine eigens implementierte Queue schreiben. die mainloop soll dann diese queue auslesen. So weit so gut! Aber wie synchronisiere ich nun die lese- und schreibe funktion meine Queue, bzw. wie machte ich das "thread-safe"! die einglieder und ausgliederung in der Queue erfolg über mehrer operationen , und ist so nich "atomar". Den interrupt auszuschalten, wenn die mainloop die queue lesen will kommt nich in frage, da in dem augenblick ja daten am CANbus von außen ankommen können. Habt ihr irgendwelche tipps??? Oder is das so nich mögich, und ich muss mich mit dem 3fach fifo vom can controller zufrieden geben! Grüße
Du brauchst einen Ringpuffer, oder FIFO. Den kann man atomar aufbauen, so dass man keine Interrupts sperren muss.
und wie soll das gehen? tipps? eine implementation eines fifo erfordert ja einige pointer ahritmetik, d.h. ich muss einige pointer zuweisen umbiegen etc. um ein element in den fifo einzugliedern bzw. auszugliedertn..!? oder gibts da Konzeote bei denen es atomar geht?? wo find ich sowas?;) grüße
Verwende eine byte (char, uint8_t) Variable als Lock für die Queue
ich will aber nix locken, sonder die operationen atomar machen.. aber wie??;)
Atomar bedeutet: nicht (durch Interrupts) unterbrechbar. Wenn du das willst, musst du eben die Interrupts sperren?! Kommt mir vor, als wüsstest du noch nicht ganz, was du genau willst. Wenn es nur um Thread safety geht, das geht auch mit locks. Aber ich vermute, dass sich der Aufwand nicht lohnt, da bei Ringpuffern immer nur für wenige Takte gesperrt werden muss.
ich will die zugriffe auf den ringpuffer (atomar) machen, so dass es zu keinem undfinierten verhalten kommt, wenn "zufällig" der interrupt die "ausgliederung" eines elemens des ringpuffers in der mainloop unterbricht, und ein neues element eingliedert... den interrupt zu sperren könnte zum verlusst von daten führen, wenn genu zu dem zeitpunkt der der sperrung daten ankommen...
>wenn genu >zu dem zeitpunkt der der sperrung daten ankommen... Nein. Du schreibst ganz oben: >darin wird die CAN-Controller FIFO Also?
NullBockException schrieb: > Den interrupt auszuschalten, wenn die mainloop die queue lesen will > kommt nich in frage, da in dem augenblick ja daten am CANbus von außen > ankommen können. Die gehen nicht verloren, wenn einige wenige bis einige zig Takte die Interrupts usgeschaltet sind. Queue-Operationen bedeuten - richtig durchgeführt - nicht, dass die Interrupts für die Dauer der kompletten Verarbeitung einer eingelaufenen Message gesperrt werden müssen.
NullBockException schrieb: > den interrupt zu sperren könnte zum verlusst von daten führen, wenn genu > zu dem zeitpunkt der der sperrung daten ankommen... Interrupts-nicht-verstanden-Error in Zeile 2. Eine einlaufende Message setzt das Interrupt-Flag. Sind da grad die Interrupts ausgeschaltet, dann kommt der Interrupt zwar nicht sofort durch, dafür aber in dem Augenblick, in dem der Interrupt wieder eingeschaltet wird. Da geht also nichts verloren. Erst wenn mehr Messages einlaufen als im CAN-Controller Puffer dafür existieren und bis dahin immer noch nichts abgeholt wurde, dann geht etwas verloren.
Ohh ok, danke IHR habt recht :) Ich beschäftige mich noch nich soo lang mit Mircocontroller programmierung.. wieder was dazugelernt:) Super, dann puffer ich quasi mit dem CAN controller fifo meine eingliederungszeit in die queue;) danke;)
bei mir hat sich double buffering in queues bewährt. Ist zwar nicht ganz atomar aber die Zeit in denen sich der erzeugerthread und der verarbeitende thread in die quere kommen können wird stark minimiert.
benwilliam schrieb: > bei mir hat sich double buffering in queues bewährt. > Ist zwar nicht ganz atomar aber die Zeit in denen sich der > erzeugerthread und der verarbeitende thread in die quere kommen können > wird stark minimiert. Und damit wird der Fehler im Zweifelsfalle noch schwieriger aufzufinden sein. Ringpuffer/Queues mit Double Buffering klingt für mich etwas unpassend zusammen. Erklär mal.
Simon K. schrieb: > Und damit wird der Fehler im Zweifelsfalle noch schwieriger aufzufinden > sein. > Ringpuffer/Queues mit Double Buffering klingt für mich etwas unpassend > zusammen. Erklär mal. eigentlich sehr simpel ... man hat 2 queues in einen werden neue eingehende messages reingeschrieben im anderen werden die vorhanden messages rausgenommen und verarbeitet. Hat der verarbeitende Thread alle nachrichten aus der 2. queue verarbeitet switcht er die queues dazu wird ein lock gesetzt und die beiden pointer der queues vertauscht. Das sind 5 zuweisungsoperationen 1 lock setzen 3 pointer tauschen (inkl. hilfvariable) 1 lock freigeben Der erzeuger Thread muss lediglich auf das lock achten
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.