Forum: Mikrocontroller und Digitale Elektronik Interruptroutinen beim XMEGA


von Tobias Hagemeier (Gast)


Lesenswert?

Moin,

ich hatte gestern bei einem Projekt komische Probleme. Ab und zu, nach 
diverser Zeit, lief der µC nicht mehr weiter (wie im Betreff angedeutet 
ein XMega).
Gerade bin ich im Datenblatt auf etwas gestoßen: Der XMEGA ja einen 
neuen Interrupt-Controller, der mehrere Prioritäten erlaubt. Bisher war 
ich davon ausgegangen, dass dies dazu dient mehrere Interrupts bei 
gesetztem Flag in eine Reihenfolge zu bringen. Im Datenblatt steht jetzt 
allerdings, dass Interrupts mit höherer Priorität solche mit niedriger 
Priorität unterbrechen können.
Da könnte die Ursache der Fehler liegen, die ich habe. Ich war 
eigentlich davon ausgegangen, dass andere Interrupts wenn ich mit 
ISR(..) arbeite automatisch deaktiviert sind. Nachdem ich ins 
Assembler-Listing geguckt habe, habe ich allerdings keine Stelle 
gefunden, wo die Interrupts deaktiviert würden. Das scheint beim halben 
"Anpassen" des GCC auf den XMEGA übersehen worden zu sein. Die 
Verhaltensweise von SIGNAL (war das dabei?) ist ja, die Interrupts nach 
aufruf der ISR speziell wieder frei zu geben; beim XMEGA ist es jetzt ja 
genau andersrum - die Interrupts müssen explizit gesperrt werden wenn 
man "für sich" sein will.

Kann jemand bestätigen, dass die Interrupts beim XMEGA im der mit "ISR" 
deklarierten Interrupt-Routine weiter an bleiben? Kann man da ohne 
Bedenken mit cli() arbeiten? Das I-Bit müsste doch nur für den initialen 
Aufruf der ISR von Bedeutung sein, oder?

Danke für die Anregungen,

Tobi

von Avr N. (balze)


Lesenswert?

Moin Tobi,

Tobias Hagemeier schrieb:
> ...habe ich allerdings keine Stelle
> gefunden, wo die Interrupts deaktiviert würden. Das scheint beim halben
> "Anpassen" des GCC auf den XMEGA übersehen worden zu sein.

Nein, das ist bestimmt nicht uebersehen worde, sondern bestimmt so 
gewollt.
Der PMIC kann nur dann eine ISR mit niedriger Prioritaet von einer ISR 
mit hoeherer Prioritaet unterbrechen lassen, wenn die Interrupts auch 
aktiviert sind.

> Kann jemand bestätigen, dass die Interrupts beim XMEGA im der mit "ISR"
> deklarierten Interrupt-Routine weiter an bleiben? Kann man da ohne
> Bedenken mit cli() arbeiten? Das I-Bit müsste doch nur für den initialen
> Aufruf der ISR von Bedeutung sein, oder?

Kann ich weder besaetigen, noch dementieren.
Ich bin aber auch noch nicht in die Situation gekommen alle Interrupts 
ausschalten zu muessen.

Mit geschickter (sinnvoller) Auswahl der Prioritaeten und des 
Schedulings der ISRs mit niedrigster Prioritaet bin ich immer gut 
zurecht gekommen.

Und wenn Du eine ISR hast, die nicht unterbrochen werden darf, gib ihr 
die hoechste Prioritaet. Dann wird sie nicht unterbrochen, selbst wenn 
die anderen Interrupts noch aktiviert sind.

(Wenn Du erst bei einem Problem ueber den PMIC gestolpert bist, .... 
kennst Du das Eventsystem des XMega? Das hat bei mir viele ISRs 
ueberfluessig gemacht.)

MfG,

Balze aka AVR Noob

von Tobias Hagemeier (Gast)


Lesenswert?

Hi Balze,

ich bin im Moment auf der Arbeit und kann das alles hier nicht 
ausprobieren. Meine Vermutung war, dass einige meiner Interrupts mehr 
oder weniger gleichzeitig auftreten und ich wollte durch die 
unterschiedlichen Prioritäten erreichen dass gleichzeitige Events (USART 
als SPI-Master mit RXC und TXC, die ja gleichzeitig eintreffen sollten) 
in der richtigen Reihenfolge abgearbeitet werden. Das macht in meinem 
Code keinen wirklichen Unterschied, hätte nur eventuell die 
Kommunikation etwas beschleunigt.

Das Eventsystem habe ich selbst noch nicht benutzt sondern darüber nur 
im Datenblatt gelesen. Meine "große Sache" für die ich die vielen 
(insgesamt 5 pro Seite) Interrupts benutze ist das Abspielen einer 
Wavedatei von einer SD-Karte. Um da auf Geschwindigkeit zu kommen und 
trotzdem möglichst flexibel zu sein lese und schreibe ich nur über die 
Interrupts - benutze parallel aber für größere Datenmengen auch noch den 
DMA-Controller (= noch mehr Interrupts). Die sollten sich eigentlich 
alle gegenseitig aktivieren/deaktivieren, wenn dann aber sobald ein 
Interrupt enabled wird der aufgrund höherer Priorität den laufenden 
Interrupt "abwürgt" kriege ich natürlich Race Conditions rein..

Ich habe jetzt mal alle Interrupts auf die gleiche (niedrige -> round 
robin) Priorität gesetzt und werde das heute abend mal testen.

Da ich es mit unterschiedlichen Prioritäten getestet habe und es damit 
ja eine Zeit lang lief kann ich mir eigentlich keine andere Ursache für 
die Probleme vorstellen. Solange das Entzahnt ist, sollte dann auch 
alles laufen - hoffe ich ;-)
Sonst muss ich da noch mit dem Debuggen anfangen. Das ist bei 375 Zyklen 
pro Sekunde auf Seite der SD-Karte noch machbar, spätestens bei den 6kHz 
auf Seite des Audio-Chips wirds dann aber mit Debug-Output über UART 
recht schwierig, da der Fehler ja von solchen weiteren laufenden 
Interrupts auch noch beeinflusst wird.

Gruß,

Tobi

von Avr N. (balze)


Lesenswert?

Hallo Tobi,

nix fuer ungut, (ich bin ja der AVR Noob ;-) aber wenn Du mit Deinen 
Interrupts "Race Conditions" erzeugen kannst, solltest Du vielleicht 
nochmal uber das Konzept nachdenken !?

Wie gibst Du denn die WAV Datei aus ? Per Port an einen Audio-DAC, oder 
per internem DAC ? vielleicht sogar Timer gesteuert ?
Falls ja, solltest Du Dich unbedingt mit dem Eventsystem beschaeftigen.

Das kann Dir das schreiben per DMA an den DAC getriggert vom Timer 
komplett abnehmen!!!
Das Eventsystem ist echt cool.

Ich habe einen Incrementalgeber-Simulator geschrieben.
Dabei lese ich per DMA (getriggert von einem Timer) den  zu 
simulierenden Geberzustand und schreibe den gelesenen Wert an einen 
Port. Der Timer ist auf PWM gestellt, die PWM auf einen Puls pro 
Zaehlerdurchgang.
So habe ich mir eine Incrementalgeber gebaut, der OHNE Software (nur die 
Initialisierungen des Timers, DMA, Port und Eventsystems) auskommt.

Nur auf zwei Taster wird per ISR reagiert um die "simulierte" Drehzahl 
zu incrementiern oder decrementieren.
So schaffe ich die drei Signale A, B und N mit 4096 Teilungen und 
Drehzahlen von ueber 5000 min-1.

Alles ohne die CPU zu benutzen.

Also meine Empfehlung: Eventsystem. Und Du bist einige Probleme los.

MfG,

Balze aka AVR Noob

von Tobias Hagemeier (Gast)


Lesenswert?

Moin Balze,

leider ist es nicht so einfach. Ich kann benutze den VLSI 1053 für die 
Analogschnittstelle - später soll der Player auch mal MP3s abspielen 
können (die große Datenmenge der Waves ist aber hier eher eine 
Herausforderung, deshalb der Fokus zunächst mal darauf).
Der VLSI-Chip signalisiert mir per High-Pegel auf einem Pin das ich 
weitere Daten senden soll, das erledigt dann der DMA-Controller. Die 
Adresse für die nächsten 32 Bytes (leider nicht mehr..) muss ich dann 
jedes mal konfigurieren und das ganze auch noch im Single-Shot-Modus 
übertragen. Da der USART.DATA-Buffer leer sein muss (DRE-Flag) UND der 
Pin hoch gezogen komme ich mit dem Eventsystem da leider nicht weiter; 
eine UND-Verknüpfung kriegt man damit soweit ich weiß nicht hin.
Wenn die Datenblöcke dann raus geschickt sind, muss ich auf den Transfer 
Complete-Interrupt warten, um Chip select abzuschalten. Das ginge zwar 
per Eventsystem (Port auf High setzen), gleichzeitig muss aber auch der 
DRE-Interrupt wieder an, damit die nächsten Daten geschickt werden 
können.
Alles etwas haarig und für "simpel" mit Eventsystem mMn nicht geeignet.

Und ja, Race Conditions kriegt man recht schnell hin wenn man die 
gleichen (teils auch 32-Bit-)Variablen in den Interrupts verwendet, aber 
nicht damit rechnet das die Interrupt-Routine von einer anderen 
unterbrochen werden kann, die auf der gleichen Variable rumgurkt. Da 
müsste man dann kritische Bereiche einbauen, woran ich halt bei den 
"normalen" ATMega-Interruptroutinen nicht gewöhnt war.
Ich habe jetzt wie gesagt alle Prioritäten auf LOW gesetzt und werde 
dann mal probieren wie es läuft. Ich erwarte da eigentlich keine 
Probleme - meine gestern im Test erreichten 400 KByte/Sekunde sollte ich 
ja trotzdem schaffen.
Die Laufzeit des Gesamtsystems ändert sich ja nicht dadurch, dass die 
Interrupts jetzt nicht mehr verschachtelt ablaufen.

Daumen drücken ;)

Gruß,

Tobi

von Avr N. (balze)


Lesenswert?

Tobias Hagemeier schrieb:
> Daumen drücken ;)

Mach ich !!  :)

Viel Erfolg!

MfG, Balze aka AVR Noob

von Tobias Hagemeier (Gast)


Lesenswert?

Kurze Rückmeldung: Es hat funktioniert. Läuft jetzt seit 30 Minuten ohne 
Probleme. Zur Sicherheit wird die Schaltung die nächste Nacht durch 
Musik spielen ;-)

Danke für deine Anregungen,

Tobi

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.