Forum: Mikrocontroller und Digitale Elektronik STM32: Races, Interrupts und Queues


von Gehsen (Gast)


Lesenswert?

Wie behandelt man auf einem STM32 am besten das entnehmen von Werten aus 
einer per Interrupt gefüllten Queue in der mainloop? Konkret geht es um 
das absichern beim verändern der Queuepointer gegen das eintreten eines 
"gleichzeitigen" Interrupts.

Sollte man Interrupts abschalten während der Zeit? Können die Interrupts 
einzeln abgeschaltet werden? Gibt es bessere Möglichkeiten? Haben die 
Cortexe spezielle Mechanismen für dieses Problem?

von Falk B. (falk)


Lesenswert?

@ Gehsen (Gast)

>Sollte man Interrupts abschalten während der Zeit?

Ja. Siehe Interrupt.

>Können die Interrupts
>einzeln abgeschaltet werden?

Ja.

> Gibt es bessere Möglichkeiten?

Es reicht meistens, die Interrupts global zu sperren. Die paar us 
schaden seltenst.

> Haben die Cortexe spezielle Mechanismen für dieses Problem?

Keine Ahnung.

von Little B. (lil-b)


Lesenswert?

Du willst dein Programm also Threadsafe machen.
Das ist vor allem eine Software sache, die Möglichkeiten entsprechend 
nahezu unbegrenzt.

Häufig reicht es, die Reihenfolge der Speicherzugriffe zu durchdenken. 
Zum Beispiel erst Daten in die Queue schreiben/lesen, danach erst den 
Pointer weiterschieben (wenns ein FIFO Ringbuffer ist).
Oder du versuchst, "Atomic Instructions" zu verwenden, jedoch wird das 
wohl eher schwierig bei einer queue.
Du kannst dir auch Mutexes und Semaphores basteln, oder nimmst ein RTOS, 
welches diese schon mitliefert.

Der Cortex hat tatsächlich einen Speziellen Mechanismus für exklusiven 
Speicherzugriff. Siehe hierzu LDREX, STREX und CLREX deines Programming 
Manuals.

Natürlich wäre CPSID und CPSIE am einfachsten, um eine Critical Section 
exklusiver Rechte zu verschaffen, aber beachte die Auswirkungen auf dein 
komplettes Projekt!

von Klaus (Gast)


Lesenswert?

Hallo, so wie du dein Problem beschreibt, kann man das mit 
Read/WritePointern OHNE IntSperre lösen. D.h. wenn du im INT schreibst 
kann die Funktion im MAINLOOP lesen.

von Gehsen (Gast)


Lesenswert?

Klaus schrieb:
> Hallo, so wie du dein Problem beschreibt, kann man das mit
> Read/WritePointern OHNE IntSperre lösen. D.h. wenn du im INT schreibst
> kann die Funktion im MAINLOOP lesen.

Muß ich mir nochmal in Ruhe durch den Kopf gehen lassen. Möglicherweise 
wenn man das auslesen der Daten und den Pointerupdate in der richtigen 
Reihenfolge macht. Evtl. kriegt man den kritischen Abschnitt auch 
kleiner.

Interrupts auf dem STM32 sind schon ein Kracher :-()

von Markus M. (adrock)


Lesenswert?

Wurde ja schon alles geschrieben, bei einem FIFO ist es durchaus unnötig 
den füllenden Interrupt zu sperren:

IRQ: Erst Wert in Buffer schreiben, DANN den Schreibpointer erhöhen
Prozess: Erst den Wert lesen, DANN den Lesepointer erhöhen (ist nur 
Relevant wenn der Interrupt testet ob der Buffer voll ist).

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.