µC: Interrupt Priorities und Warteschlange

OP Persönliche Seite #4312403
Lesenswert?

Erstmal zum Klären (auch um eventuelle Verständnislücken von vorneherein 
offen zu legen): Nach meinem Verständnis funktioniert das 
Interrupt-Priority-Management auf Atmel Controllern (und generell?) so, 
dass Interrupts mit niedrigier Priorität nur ausgelöst werden können, 
wenn gerade nicht einer mit höherer Prio am laufen ist. D.h.: Höhere 
Priorität darf niedrigere unterbrechen, aber nicht andersherum...?

Ich habe nun zwei SPI devices, die beide über einen h/l-pegel zeigen, 
wenn daten bereit sind. das (bezgl definierter Zeitbasis) wichtigere 
device löst mit einem Data_Ready pin einen Interrupt mit hoher priorität 
aus.
Das zweite device, das weniger (menge) und weniger wichtige daten 
bereitstellt, wird in der main loop über eine pinabfrage geprüft 
(bislang ohne Interrupts).

Das Problem bei diesem Herangehen ist ja nun: Überschneidet sich der 
Interrupt des ersten SPI slaves mit der Ausführung des Daten Holens vom 
zweiten gibts Bockmist auf dem SPI interface. Natürlich kann ich 
Interrupts (global) abschalten, wenn ich die Daten hole - nur verfällt 
dann der Interrupt des wichtigeren SPI slaves..?

Wie sieht ein gutes management aus in einem solchen Fall? Also:

SPI Slave 1: Höhere Datenrate, höchste Priorität diese sofort zu holen
SPI Slave 2: Niedrigere Datenrate, "wann holen" eigentlich egal, nur 
vorm nächsten zyklus.
#4312414
Lesenswert?

Alex V. schrieb:
> Wie sieht ein gutes management aus in einem solchen Fall

Man nehme einen Mikrocontroller mit 2 unabhängigen SPI (oder z.B. USART) 
Schnittstellen. Dann kannst Du eine im Interrupt und eine in der 
Hauptschleife nutzen.

Beim ollen Atmega müsstest Du das SPI in der Hauptschleife als Software 
SPI ausführen, da die nur einmal SPI HW haben.
Gast #4312425
Lesenswert?

Alex V. schrieb:
> Natürlich kann ich
> Interrupts (global) abschalten, wenn ich die Daten hole - nur verfällt
> dann der Interrupt des wichtigeren SPI slaves..?

Wenn du Data_Ready mit edge trigger benutzt dann ja.

Du könntest den Interrupt auf Level Trigger stellen. Dann löst der 
Interrupt aus sobald du die Interrupts wieder aktivierst, da Data_Ready 
ja weiterhin low ist (das Gerät wurde ja noch nicht abgefragt bisher).



Alex V. schrieb:
> ganz zuletzt noch den Status des zweiten zu prüfen und dann am
> Ende und Innerhalb der IR die daten zu holen.

Dann würde es auch mit Edge Trigger klappen. Außer der Pegel ändert sich 
genau zwischen der Statusabfrage und dem Ende des Interrupthandlers. 
Dann wirst du den geänderten Status nie mitbekommen.
Gast #4312426
Lesenswert?

Alex V. schrieb:
> Erstmal zum Klären (auch um eventuelle Verständnislücken von vorneherein
> offen zu legen): Nach meinem Verständnis funktioniert das
> Interrupt-Priority-Management auf Atmel Controllern (und generell?) so,
> dass Interrupts mit niedrigier Priorität nur ausgelöst werden können,
> wenn gerade nicht einer mit höherer Prio am laufen ist. D.h.: Höhere
> Priorität darf niedrigere unterbrechen, aber nicht andersherum...?

Atmel Controller? Welchen? Bei AVR können Interrupts andere ISR im 
"Normalfall" nicht unterbrechen. Stehen mehrere Interrupts gleichzeitig 
zur Abarbeitung an, wird jede ISR bis zum Ende nach einer 
Abarbeitungsreihenfolge ausgeführt. Sowas kann man dem jeweiligen 
Datenblatt entnehmen.
#4312441
Lesenswert?

@Alex V. L. (bastel_alex) Benutzerseite

>offen zu legen): Nach meinem Verständnis funktioniert das
>Interrupt-Priority-Management auf Atmel Controllern (und generell?)

WELCHE Familie? Atmel baut sehr mehrere, verschiedene Familien?

>so,
>dass Interrupts mit niedrigier Priorität nur ausgelöst werden können,
>wenn gerade nicht einer mit höherer Prio am laufen ist. D.h.: Höhere
>Priorität darf niedrigere unterbrechen, aber nicht andersherum...?

Ist nicht allgemein so, siehe Interrupt

>Das Problem bei diesem Herangehen ist ja nun: Überschneidet sich der
>Interrupt des ersten SPI slaves mit der Ausführung des Daten Holens vom
>zweiten gibts Bockmist auf dem SPI interface. Natürlich kann ich
>Interrupts (global) abschalten, wenn ich die Daten hole -

Das musst du auch, wenn ein ein einzigr SPI Bus ist.

> nur verfällt
>dann der Interrupt des wichtigeren SPI slaves..?

Nö. Siehe Interrupt.

>Wie sieht ein gutes management aus in einem solchen Fall? Also:

Kann man allgemein nicht sagen, dazu braucht man mehr Informationen, vor 
allem zur Häufigkeit.

>SPI Slave 1: Höhere Datenrate, höchste Priorität diese sofort zu holen
>SPI Slave 2: Niedrigere Datenrate, "wann holen" eigentlich egal, nur
>vorm nächsten zyklus.

Eine Möglichkeit wäre, am Ende eines jeden SPI 1 Zugriffes zu prüfen, ob 
ein SPI 2 Zugriff nötig ist. Wenn ja wird ein Flag gesetzt und dieses in 
der Hauptschleife ausgewertet. Damit ist man relativ sicher, das in 
"nächster Zeit" erstmal kein neuer SPI 1 Zugriff ansteht. Trotzdem muss 
man den Interrupt für SPI 1 zeitweilig sperren, damit es wasserdicht 
wird.
OP Persönliche Seite #4312442
Lesenswert?

foo schrieb:
> Du könntest den Interrupt auf Level Trigger stellen. Dann löst der
> Interrupt aus sobald du die Interrupts wieder aktivierst

ach ja, klar! danke!

Ich habe grade ausprobiert, was ich oben angedeutet habe:

SPI_Slave1: Interrupt (Flanke) mit hoher prio (gegen alle anderen IRs 
der routine), am Ende der Slave1_IR pegel des Data_rdy des SPI_Slave2 
überprüfen (nicht Interrupt basiert) und ggf. daten holen. Klappt in 
diesem Fall (ich bekomme keinen SPI murks mehr zwischenzeitlich) - aber 
nur deshalb, weil Slave1 10 mal öfter daten bereitstellt (die abfrage 
ist also häufig genug)..

Edit: Ja so ungefähr
Falk B. schrieb:
> Eine Möglichkeit wäre, am Ende eines jeden SPI 1 Zugriffes zu prüfen, ob
> ein SPI 2 Zugriff nötig ist. Wenn ja wird ein Flag gesetzt und dieses in
> der Hauptschleife ausgewertet. Damit ist man relativ sicher, das in
> "nächster Zeit" erstmal kein neuer SPI 1 Zugriff ansteht. Trotzdem muss
> man den Interrupt für SPI 1 zeitweilig sperren, damit es wasserdicht
> wird.
#4312453
Lesenswert?

Alex V. schrieb:
> Nach meinem Verständnis funktioniert das
> Interrupt-Priority-Management auf Atmel Controllern

Welcher denn?

Bei den Atmel 8051 (z.B. AT89LP51) gibt es 4 Prioritätslevel, d.h. 
maximal kann ein Interrupt von bis zu 3 anderen mit höherem Level 
unterbrochen werden.
Die Level sind für jeden Interrupt einzeln auswählbar und können auch 
innerhalb des Handlers geändert werden. Ist das Interruptflag immer noch 
gesetzt und man erhöht den Level, kann sich der Interrupt selber durch 
eine 2. Instanz unterbrechen. Der unterbrochene behält dabei ihren alten 
Level.

Daneben gibt es noch die Polling Sequenz, falls bei Interruptfreigabe 
mehrere Interruptflags gesetzt sind. Sie entspricht der 
Vektorreihenfolge und ist daher fest. D.h. der Interrupt mit der 
niedrigsten Vektoradresse wird zuerst ausgeführt.

Das trifft aber nur für die Atmel 8051 zu, nicht für die Atmel AVR, 
Atmel xmega, Atmel AVR32, Atmel Cortex usw.
OP Persönliche Seite #4312469
Lesenswert?

Peter D. schrieb:
> Welcher denn?
>
> Bei den Atmel 8051 (z.B. AT89LP51) gibt es 4 Prioritätslevel, d.h.
> maximal kann ein Interrupt von bis zu 3 anderen mit höherem Level
> unterbrochen werden.
> Die Level sind für jeden Interrupt einzeln auswählbar und können auch
> innerhalb des Handlers geändert werden. Ist das Interruptflag immer noch
> gesetzt und man erhöht den Level, kann sich der Interrupt selber durch
> eine 2. Instanz unterbrechen. Der unterbrochene behält dabei ihren alten
> Level.

Danke für die Ausführung! Beim Sam4s ist das der Fall (allerdings mehr 
Prioritätslevel, soweit ich weiß).
(Firma: EDF) #4312504
Lesenswert?

Meiner Ansicht nach läßt sich eine laufende Übertragung nicht einfach 
"unterbrechen" d.h. egal welche Priorität dein "wichtiger" SPI Baustein 
haben soll, muss zunächst die laufende Transaktion fertig gemacht 
werden.

Mann kann normalerweise nicht einfach ein Chip deselektieren, was 
anderses machen den Chip wieder selektieren und er macht einfach da 
weiter wo er aufghört hat.

du musst eine nieder Priore Übertragung schon geziehlt abbrechen. d.h du 
musst auch hier den anderen Pin abfragen, Die laufende Übertragung 
irgentwie eintüten, so dass du weist, wo du sie wieder aufnehmen kannst.

mfg
Gast #4312571
Lesenswert?

Alex V. schrieb:

> Erstmal zum Klären (auch um eventuelle Verständnislücken von vorneherein
> offen zu legen): Nach meinem Verständnis funktioniert das
> Interrupt-Priority-Management auf Atmel Controllern (und generell?) so,
> dass Interrupts mit niedrigier Priorität nur ausgelöst werden können,
> wenn gerade nicht einer mit höherer Prio am laufen ist. D.h.: Höhere
> Priorität darf niedrigere unterbrechen, aber nicht andersherum...?

Nein. Bei AVR8-Controllern z.B. gibt es keine echten 
Interruptprioritäten in dem Sinne, wie du sie verstehst. Hier steuert 
die Priorität nur die Reihenfolge der ISR-Auslösung, wenn (quasi-) 
gleichzeitig mehr als ein IRQ erfolgt. Wenn ein Interrupt erst einmal 
ausgelöst ist, dann spielt die Priorität keinerlei Rolle mehr, dann wird 
die ISR abgearbeitet, bis sie fertig ist oder zumindest die Interrupts 
wieder frei gibt. Bis zu diesem Zeitpunkt spielt es dann keine Rolle, ob 
ein weiterer Interrupt mit höherer Priorität ausgelöst wurde. Der kann 
die laufende ISR nicht unterbrechen.

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