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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.