Forum: Mikrocontroller und Digitale Elektronik µC: Interrupt Priorities und Warteschlange


von Alex V. (bastel_alex) Benutzerseite


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.

: Bearbeitet durch User
von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Eine Möglichkeit bestünde ja darin, im Interrupt des wichtigeren SPI 
devices ganz zuletzt noch den Status des zweiten zu prüfen und dann am 
Ende und Innerhalb der IR die daten zu holen.
Dabei kämen sich beide dann nicht in die Quere, nur die IR würde etwas 
länger...

von Jim M. (turboj)


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.

von Jim M. (turboj)


Lesenswert?

Alex V. schrieb:
> Eine Möglichkeit bestünde ja darin, im Interrupt des wichtigeren SPI
> devices ganz zuletzt noch den Status des zweiten zu prüfen

Das klappt in der Praxis nicht, die meisten Geräte brauchen SPI 
Transaktionen die länger als ein Byte sind.

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Jim M. schrieb:
> 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.

Bereits genommen: ATSAM4S. Hat zwar mehrere SPI schnittstellen, nun 
hängen aber beide slaves an der selben...

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Jim M. schrieb:
> Das klappt in der Praxis nicht, die meisten Geräte brauchen SPI
> Transaktionen die länger als ein Byte sind.

ist hier auch der fall - aber ich verstehe noch nicht, wieso das in der 
Routine ein problem darstellt?

von foo (Gast)


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.

von Bon (Gast)


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.

von Falk B. (falk)


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.

von Alex V. (bastel_alex) Benutzerseite


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.

: Bearbeitet durch User
von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Zur Familie und ist nicht immer so: Hätte ich mir ja denken können, dass 
die Aussage so allgemein nicht richtig ist. Habe ich mir ja auch fast 
gedacht, deshalb steht sie extra nochmal anfechtbar da. ;D

"Hängt von der Familie ab" ist also notiert - in diesem Fall, s.o. (wie 
schon länger bei mir) die ATSAM4S...

von Peter D. (peda)


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.

von Alex V. (bastel_alex) Benutzerseite


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

von D. F. (Firma: EDF) (derdan)


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

von c-hater (Gast)


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.

von Peter D. (peda)


Lesenswert?

Die meisten seriellen Busse sind nicht reentrant, d.h. sie darf nur eine 
Instanz zur Zeit belegen.
Aber die standard AVRs haben ein SPI und bis zu 4 UARTs, die als 
SPI-Master konfiguriert werden können, d.h. 5 separate SPI-Ports.

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.