Forum: Mikrocontroller und Digitale Elektronik Übertragung mittels Interrupt Priorität sichern


von A. F. (artur-f) Benutzerseite


Lesenswert?

Mein Atmega muss Daten von verschiedenen Schnittstellen(3) verarbeiten. 
Usart und I2C sind Interrupt gesteuert. Ich möchte jedoch eine sichere 
Übertragung haben, dass die Daten unabhängig von den 3 Schnittstellen 
mit Sicherheit verarbeitet werden. TIMER2 hat z.B. die höhere Priorität 
als die anderen zwei. Kann ich jedes Mal, wenn Daten über 3 verschiedene 
Schnittstellen ankommen, TIMER2 starten und dort in der ISR meine Daten 
ungestört verarbeiten? Und erst dann auf weitere Anfragen von USART, I2C 
etc reagieren?
TIMER2 wird sonst nicht genutzt. Macht man das so? Andere Idee habe ich 
z.Z. nicht.

von Matthias L. (Gast)


Lesenswert?

>Kann ich jedes Mal, wenn ..., TIMER2 starten und dort in der ISR meine Daten
>ungestört verarbeiten?

WOzu? lass den Timer2 ganz weg.
Nutze einfach die entsprechenden Interrupts (für USART, TWi,..)
Programmiere die ISR jedoch so, dass sie möglichst kurz sind. Am Besten 
das empfangene Datum entgegen nehmen und in einen (FIFO-Ring)Puffer 
eintragen. ISR fertig.

Um die Auswertung der Daten (in entsprechenden Puffer) muss sich die 
main kümmern. Die hat Zeit...

von Johannes M. (johnny-m)


Lesenswert?

Prioritäten der Interrupts im Sinne von "Interrupt A kann Interrupt B 
unterbrechen" gibt es bei den AVRs zunächst mal gar nicht. Die 
"Prioritäten", die sich aus der Reihenfolge der Interrupt-Vektoren in 
der Tabelle ergeben, sind lediglich dann von Interesse, wenn mehrere 
Interrupt-Ereignisse gleichzeitig auftreten und es darum geht, welcher 
Interrupt zuerst abgearbeitet wird. Generell sperrt die Hardware bei 
Auftreten eines Interrupt-Ereignisses die Bearbeitung aller anderen 
Interrupts.

Wenn man möchte, dass ein Interrupt einen anderen Interrupt Handler 
unterbrechen kann, dann muss man dafür sorgen, dass die 
Interrupt-Bearbeitung im Interrupt-Handler, der unterbrechbar sein soll, 
freigegeben wird. Allerdings ist das i.d.R. keine gute Lösung. Deine 
Angaben hören sich an, als ob Du innerhalb der Interrupt Handler schon 
irgendwelche komplexen Datenverarbeitungen machst, wodurch die Handler 
zu lang werden. Interrupt Handler sollten aber generell so kurz wie 
möglich sein. Wenn es eben geht (und das sollte gerade bei den eher 
langsamen seriellen Schnittstellen überhaupt kein Problem sein), sollte 
man im Interrupt Handler nur die entsprechenden Datenregister 
verarbeiten und die Daten in einen (globalen) Puffer schreiben. Die 
eigentliche Datenverarbeitung hat im Interrupt Handler nichts zu suchen, 
die gehört ins Hauptprogramm. Serielle Datenübertragung über USART und 
I²C kann sowieso im Regelfall als eher langsam angesehen werden (ich 
weiß nicht, mit welchen Taktfrequenzen Du die betreibst, aber 
normalerweise ist da genügend Zeit zwischen zwei Interrupts zur 
Verarbeitung der Daten im Hauptprogramm, ohne dass etwas verloren geht).

von A. F. (artur-f) Benutzerseite


Lesenswert?

>I²C kann sowieso im Regelfall als eher langsam angesehen werden (ich
>weiß nicht, mit welchen Taktfrequenzen Du die betreibst, aber
>normalerweise ist da genügend Zeit zwischen zwei Interrupts zur
>Verarbeitung der Daten im Hauptprogramm, ohne dass etwas verloren geht)

Das ist es ja, wenn ich sensible Daten über eine Schnittstelle zu einem 
anderen µC sende, kommen teilweise schon von einem 3ten µC neue Daten, 
die eine noch nicht vollendete Übertragung stören. So kommen z.B. 2 Byte 
von 8KByte über ein parallel Interface fehlerhaft an. Diese 
Schnittstelle die ohne ISR arbeitet, hat dann gegen USART und I2C ISR 
keine Chance. Fange ich jedoch über die Schnittstelle in der I2C ISR zu 
senden, wird diese nicht unterbrochen und alle 8Kbyte kommen heile an. 
Deshalb meine Idee, unabhängig von der Schnittstelle einen Flag zu 
setzen, diesen in main() abfragen und gegeben falls Timer ISR zu 
starten, wo die Pakete ungestört gehändelt werden.

von Falk B. (falk)


Lesenswert?

@ Artur F***** (artur-f)

>setzen, diesen in main() abfragen und gegeben falls Timer ISR zu
>starten, wo die Pakete ungestört gehändelt werden.

Das wird nix. Du musst schon auch die anderen Schnittstellen 
berücksichtigen. Einfach "bockig" die Interrutps ausschalten (geht 
einfaer mit SEI, ohne Timer), dreht das Problem nur um. Jetzt verhungern 
deine interruptgesteuerten Schnittstellen.

Fakt ist, dein uC muss auch die Spitzendatenströme abfangen können, wenn 
gleich mit Hilfe kleiner Softwarepuffer.

Siehe Interrupt.

MFG
Falk

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.