Hallo,
ich habe offensichtlich ein Problem mit einer race condition und komme nicht dahinter, wo die her kommt. Also zuerst mal eine so weit wie möglich vereinfachte Beschreibung des Systems.
Es gibt einen Interrupt von Timer2, der immer möglichst zeitnah ausgeführt werden soll. Deswegen kommen die normalen Mechanismen zur Serialisierung der anderen Interrupts nicht in Frage, sie würden die globale Interruptfreigabe zu lange blockieren.
Neben diesem T2-Interrupt gibt es noch zwei weitere Interruptquellen, ADC und UDRE. Deren Handler greifen auf gemeinsame Daten zu. Der jeweils andere Interrupt muß also verhindert werden, wenn einer der Handler ausgeführt wird, außerdem muß auch eine erneute Auslösung eines bereits aktiven Interrupts verhindert werden, solange dessen Handler noch läuft. Außerdem gibt es noch eine Steuerung der Interruptfreigabe für UDRE. Im UDRE-Handler kann bei Eintreten bestimmter Situationen entschieden werden, daß die Auslösung des UDRE-Int nicht mehr länger nötig ist, im ADC-Handler hingegen kann die Entscheidung fallen, daß UDRE-Auslösung doch wieder nötig wird.
Und als wäre das zusammen nicht schon kompliziert genug, ist die ADC nicht freilaufend, sondern wird vom freilaufenden Timer1 (ohne Interrupthilfe, sondern über den Autotrigger-Mechanismus) getriggert und das auch nur dann, wenn der T2-Int in bestimmten Situationen sozusagen eine Freigabe dafür erteilt.
Die Idee zur Realisierung des Systems bestand darin, die vorläufige Interruptsperrung, die normalerweise über SREG_I automatisch bei Interruptauslösung realisiert wird, so schnell wie möglich durch Sperren der einzelnen Interrupt-Enable-Flags zu ersetzen. Die Handler von ADC und UDRE sehen also in etwa so aus (ist ein Device mit MMIO, also nicht über die sts wundern, wo man eigentlich out erwarten würde, außerdem habe ich den ganzen Kram mit dem Retten von Registern und Flags weggelassen, er entspricht dem üblichen Vorgehen)
adc_int: sts UCSR0B,UARTDISABLE ;löscht UDRIE0 sts ADCSRA,ADCDISABLE ;löscht ADIE und ADATE mov ADCCTRL,ADCDISABLE ;setzt diesen Zustand als "default" für die Laufzeit des Handlers. sei ;ab hier müßte meiner Meinung nach immer noch sichergestellt sein, daß ;einerseits weder eine erneute Auslösung von ADC noch eine Auslösung von ;UDRE erfolgen kann, andererseits aber der T2-Int wieder möglich ist. ;------------------------------- ;Spiel mit den gemeinsamen Daten ;------------------------------- ;je nach Sachlage kann dabei die ;Entscheidung fallen, daß die Dienste ;von UDRE wieder benötigt werden, dann ;passiert das (ohne Berücksichtigung ;eines vorigen Zustands) durch: sbr UARTCTRL,1