Asynchroner Datenaustausch in C

Gast #4042334
Lesenswert?
• ▲
▼
Hallo zusammen,

ich wollte mal fragen was erfahrungsgemäß die beste Variante ist in C 
"asynchron" Daten auszutauschen, bspw. zwischen einer ISR und main?
In der ISR die Daten in eine Art Schattenregister schreiben und dieses 
einmal pro Endlosschleifendurchlauf auslesen oder gleich per FIFO? Oder 
lieber ständig die Interrupts ein-/ausschalten? Gibt es noch weitere 
Methoden? Hängt es von der Richtung ab (main -> ISR bzw. ISR -> main) 
was die beste Lösung ist?

Grüße,
Micha
Gast #4042344
Lesenswert?
• ▲
▼
Nehmen wir an, du willst ein Array aus einer ISR an die main übergeben, 
dann könntest du zwei globale Bits erstellen: bReading, bWriting.

ISR:

while(bReading); // wait while reading from main is finished
bWriting = 1;
copyFromISR();
bWriting = 0;


main:

while(bWriting); // wait while writing from ISR is finished
bReading = 1;
copyToMain();
bReading = 0;
(Firma: matzetronics) #4042351
Lesenswert?
• ▲
▼
Da gibts kein allgemein gültiges Rezept. Ein UART Interrupt z.B. kann 
ein empfangenes Datum speichern und evtl. noch ein Flag setzen oder 
einen Pointer behandeln.
Eine ISR, die mechanisch ausgelöst wird und was tun soll (ich emuliere 
hier z.B. gerade ein Cassettendeck) setzt nur ein Flag und der 
(langsame) Rest wird von einer Unterroutine von main() gemacht, da läuft 
parallel nämlich noch Digital Audio, das auf keinen Fall unterbrochen 
werden darf.

Generell sollten ISR schnell fertig werden und vorhersehbares 
Zeitverhalten haben. Däumchen drehen kann man in main() immer noch.
Gast #4042353
Lesenswert?
• ▲
▼
Die Methode mit Schattenregister (also faktisch double buffering) ist 
gängig. Man kann das auch recht einfach zu einem Ringpuffer mit 
FIFO-Semantik aufbohren. Das habe ich so schon häufiger genutzt. 
Interrupts ausschalten würde ich nur im Notfall machen. Manche CPUs 
haben Instruktionen für atomare komplexe Operationen, die sind ggf. 
nützlich als Alternative dazu.
#4042363
Lesenswert?
• ▲
▼
@Micha (Gast)

>ich wollte mal fragen was erfahrungsgemäß die beste Variante ist in C
>"asynchron" Daten auszutauschen, bspw. zwischen einer ISR und main?

Siehe Interrupt.

>In der ISR die Daten in eine Art Schattenregister schreiben und dieses
>einmal pro Endlosschleifendurchlauf auslesen oder gleich per FIFO?

Kommt auf die Anwendung an.

>Oder
>lieber ständig die Interrupts ein-/ausschalten?

Warum sollte man das tun? Bestenfalls für atomare Zugriffe.
Gast #4042375
Lesenswert?
• ▲
▼
C Programmierer schrieb:
> // wait while reading from main is finished

Irgendwelche Waits in der main zu haben ist nicht gut.
Warum soll ich auf einen Subtask warten, wenn ich was besseres zu tun 
habe.
Wenn in der main nix zu tun ist, dann legt man sich schlafen oder 
übergibt an den Idle-Task. Beim AVR meistens sleep.

UART-I/O kann man immer asynchron machen und die main via signale
über den aktuellen Zustand informieren.

Ich mache das schon immer so, dass ich einen Sende- und einen 
Empfangsringpuffer für den UART habe. Die ganze UART-Abwicklung macht 
die
zugehörige ISR. Jeweils eine für TX, RX und evt. UART_ERROR_HANDLING.

Viele habe damit ein Problem, weil sie sich nicht "virtuelle, 
asynchrone"
Abläufe vorstellen können.
Als Anregung kann ich nur jedem empfehlen sich mal mit einem "echten" 
RTOS
zu beschäftigen und die darin verankerte "Quasiparallelität" anzueignen.
Gast #4042422
Lesenswert?
• ▲
▼
> Was ein Quark!

Recht nettes Beispiel ist das SD-Card Zeug aus der das alten PIC 
Library. main() ruft regelmässig AsyncWriteTasks() auf. Das schaut nach, 
ob die SPI Hardware inzwischen das Interrupt-Flag gesetzt hat. ISR wird 
nicht aktiviert.
Gast #4042522
Lesenswert?
• ▲
▼
Falk Brunner schrieb:
> Siehe Interrupt.
Darin sehe ich am ehesten den Abschnitt "UART mit Interrupts" als 
relevant an und das Beispiel dort empfinde ich als relativ speziell. 
Speziell deswegen, weil vorausgesetzt wird, dass man sein Protokoll 
selbst definieren kann (\0 am Ende). Wenn dies aber nicht der Fall 
ist...?
Der Mechanismus an sich ist aber natürlich anpass- und übertragbar.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren