Forum: Mikrocontroller und Digitale Elektronik STM32: Concurrency Interrupt und mainloop


von NullBockException (Gast)


Lesenswert?

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

von Jim M. (turboj)


Lesenswert?

Du brauchst einen Ringpuffer, oder FIFO. Den kann man atomar 
aufbauen, so dass man keine Interrupts sperren muss.

von NullBockException (Gast)


Lesenswert?

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

von da1l6 (Gast)


Lesenswert?

Verwende eine byte (char, uint8_t) Variable als Lock für die Queue

von NullBockException (Gast)


Lesenswert?

ich will aber nix locken, sonder die operationen atomar machen.. aber 
wie??;)

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von NullBockException (Gast)


Lesenswert?

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...

von Groß- und Kleinschreibung (Gast)


Lesenswert?

>wenn genu
>zu dem zeitpunkt der der sperrung daten ankommen...

Nein.

Du schreibst ganz oben:

>darin wird die CAN-Controller FIFO

Also?

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von NullBockException (Gast)


Lesenswert?

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;)

von benwilliam (Gast)


Lesenswert?

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.

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von benwilliam (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.