Kapitel 6 - Interrupt Handling
← Startseite · Kap. 5 Timer · 6 Interrupt Handling · → Kap. 7 Signalverarbeitung
Verwandt: ARM-Architektur (CPSR, IRQ/FIQ) · Kap. 5 periodische Interrupts · Kap. 9 Software Interrupt
Quellen: [Q: IR] ES-07-IR Interrupt · [Q: ZF §7/§7a/§7b] · [Q: KL20 Aufg. 7] · [Q: ALT Übungsklausur]
Inhalt
- Ereignisgesteuerte Programmierung
- Mechanismen: Busy Waiting / Polling / Interrupt
- Ablauf eines Interrupts
- Interrupt Controller: AIC vs. NVIC
- Priorität, Nested, Spurious
- DMA
- Shared Data Problem
- Bewertung Polling ↔ Interrupt
- Prüfungsrelevanz
1. Ereignisgesteuerte Programmierung
- Ereignisgesteuert: Programmablauf wird durch externe Ereignisse gesteuert, nicht nur durch eigene Daten. Nötig, wenn der Rechner intensiv mit der Umwelt interagiert (GUIs, Kommunikation, Prozesssteuerung).
- Ereignisquellen: Tastatur/Maus, serielle Schnittstellen (Ethernet, USB, I²C, SPI, CAN), parallele Schnittstellen, AD/DA, Timer (periodisch, abgeschlossene Messung, RTC, Watchdog).
2. Mechanismen: Busy Waiting / Polling / Interrupt
Analogie „Warten auf einen Gast":
| Mechanismus | Analogie | Kurz |
|---|---|---|
| Busy Waiting (ohne Klingel) | an der Tür stehen und warten | Endlosschleife bis Ereignis; sofortige Reaktion, aber CPU blockiert |
| Polling (ohne Klingel) | regelmäßig zur Tür laufen und nachsehen | zyklische Abfrage; kann dazwischen anderes tun; Gefahr, Ereignisse zu verpassen |
| Interrupt (mit Klingel) | Klingel unterbricht die Arbeit | echte Nebenläufigkeit; CPU macht anderes / schläft; komplexer (Kontextwechsel) |
Polling-Code-Muster:
// Round Robin (alle gleichberechtigt)
for(;;){ if(ereignis1) job1(); if(ereignis2) job2(); if(ereignis3) job3(); }
// prioritätsgesteuert (continue = höchste Prio zuerst)
for(;;){ if(ereignis1){job1();continue;} if(ereignis2){job2();continue;} if(ereignis3){job3();continue;} }
Randbedingung Polling/Event-Loop: Reaktionsroutinen dürfen nicht warten, müssen sofort zurückkehren.
3. Ablauf eines Interrupts
Interrupt = asynchrone Unterbrechung des Befehlsstroms. Laufendes Programm wird unterbrochen, eine ISR (Interrupt Service Routine) startet.
Ablaufschritte (allgemein):
- Interruptanforderung einer HW-Komponente an den Interrupt Controller.
- Controller prüft (aktiv? Priorität?) → signalisiert der CPU einen Interrupt.
- CPU beendet aktuellen Befehl, Kontext sichern: Program Counter + Statusregister retten (ARM7:
LR_irq = PC−4,SPSR; Cortex-M: automatisch R0–R3,R12,LR,PC,PSR auf Stack). - CPU liest die ISR-Adresse (Interrupt Vector Register / Vektortabelle) → springt zur ISR.
- ISR ausführen (Ereignis behandeln).
- Interrupt bestätigen (ARM7:
EOICRschreiben). - Kontext wiederherstellen, Rücksprung (ARM7:
SUBS pc, lr, #4- stellt PC und CPSR wieder her).
sequenceDiagram
participant P as Peripherie
participant IC as Interrupt Controller (AIC/NVIC)
participant CPU as CPU / ISR
P->>IC: Interruptanforderung (IRQ)
IC->>CPU: signalisiert Interrupt (Priorität ok)
Note over CPU: Kontext sichern (PC, Statusregister)
CPU->>IC: liest ISR-Adresse (Vektor)
Note over CPU: ISR ausführen
CPU->>IC: Interrupt bestätigen (EOICR)
Note over CPU: Kontext wiederherstellen, Rücksprung
- Eigener Kontext: Die ISR braucht einen von der Anwendung unabhängigen Kontext → echte Nebenläufigkeit ohne Beeinflussung.
- Interrupt Response Time / Latenz: Zeit bis ISR-Start; hängt von aktueller CPU-Tätigkeit + Kontextwechsel-Dauer ab.
4. Interrupt Controller: AIC vs. NVIC
Mehrere unabhängige Quellen → ein Interrupt Controller verwaltet/priorisiert die Anforderungen und entlastet die CPU.
| AIC (AT91, ARM7) | NVIC (Cortex-M / SAM3X, RP2040) | |
|---|---|---|
| Name | Advanced Interrupt Controller | Nested Vectored Interrupt Controller |
| Lage | externe Peripherie | im Prozessorkern integriert |
| Prioritäten | 8 (0–7) + separater FIQ | 16 (0=höchste … 15) |
| Quellen | 32 (ID 0–31; 0=FIQ, 1=SysTimer) | bis 30 externe IRQs + System-Exceptions |
| Nested/Reentrant | nur mit expliziter Programmierung | transparent (HW) |
| Kontextsicherung | teils per Software | automatisch (Stacking) |
| Extras | Spurious-Handling | Tail-Chaining, Late-Arrival, Preemption |
AIC-Register (AT91): SMR (Trigger-Typ Flanke/Pegel + Priorität), SVR (Source Vector = ISR-Adresse je Quelle), IVR (Vector des aktiven IRQ), EOICR (End of Interrupt), IECR/IDCR (Enable/Disable). Basis 0xFFFFF000. IRQ-Vektoradresse 0x18 enthält Sprung, der PC aus AIC_IVR lädt.
NVIC-Programmierung (CMSIS): NVIC_EnableIRQ(IRQn), NVIC_DisableIRQ, NVIC_SetPriority, NVIC_ClearPendingIRQ. Vektortabelle ab 0x00000000 (verschiebbar via VTOR); unterstes Adressbit = 1 (Thumb).
Cortex-M Beschleuniger:
- Automatic Stacking: Register bei ISR-Eintritt automatisch gesichert.
- Tail-Chaining: steht am ISR-Ende gleich ein weiterer Interrupt an → kein Pop/Push, direkt in die nächste ISR (spart Zyklen).
- Late-Arrival: kommt während des Stackings ein höher priorisierter Interrupt → direkt zu diesem.
5. Priorität, Nested/Reentrant, Spurious
- Priorität: Bei mehreren gleichzeitigen Quellen wird die wichtigere zuerst bearbeitet → garantierte Reaktionszeit für hohe Priorität. AT91: 0–7 (die Klausur nennt „Priorität 7 bis 0").
- Preemption (Cortex-M): höher priorisierter Interrupt verdrängt laufenden; gleiche Priorität verdrängt sich nicht. Group- vs. Sub-Priority: nur Group entscheidet über Verdrängung, Sub-Priority über Reihenfolge gleichzeitig anstehender.
- Nested/Reentrant (ARM7): standardmäßig nicht verschachtelt (I-Bit gesetzt beim IRQ-Eintritt). Reentrant machen: in System-Mode wechseln,
LR/SPSRauf Stack sichern, I-Bit löschen (Interrupts wieder frei). - Spurious Interrupt (Geister-IRQ): Anforderung verschwindet, bevor die CPU sie verarbeitet. AIC liefert Adresse aus Spurious Vector Register (SPU) → eine Spurious-ISR ist zwingend nötig, sonst Absturz.
6. DMA
Für sehr schnelle Transfers (Gigabit-Ethernet, USB) sind SW-Interrupts zu langsam. Ein DMA-Controller überträgt Daten Peripherie↔Speicher selbstständig. Der Interrupt dient dann nur zur Ablaufkontrolle („Transfer fertig"), nicht mehr pro Byte.
7. Shared Data Problem
Wenn Hauptprogramm und ISR dieselben Daten nutzen: Ändert die ISR ein Datum, während das Hauptprogramm gerade damit rechnet → Inkonsistenz (Race Condition).
- Lösung: kritischen Abschnitt schützen - während des Zugriffs Interrupts kurz sperren (critical section). Gemeinsame Variablen als
volatile(Kap. 1 §8).
8. Bewertung Polling ↔ Interrupt
Vorteile Polling/Busy Waiting:
- Einfacher zu implementieren; Abfrage im Hauptprogramm.
- Busy Waiting reagiert sofort (kein Kontextwechsel).
- Weniger HW-Aufwand am Gerät (muss keine IRQ auslösen können; z. B. Temperatursensor braucht nur AD-Wandler).
Vorteile Interrupt:
- Hauptprogramm einfacher/klarer (keine ständige Abfrage).
- Ereignis wird immer überwacht (Polling nur zu Abfragezeitpunkten).
- CPU kann andere Aufgaben erledigen; stromsparend (Sleep bis IRQ).
- Bus/Geräte entlastet (Kommunikation nur bei echtem Ereignis).
Prüfungsrelevanz
- Ablauf-Zuordnung (KL20 Aufg. 7): Schritte [A]–[E] den Beschreibungen zuordnen: IRQ-Anforderung → Unterbrechung des Assemblerbefehls → IVR lesen → ISR-Adresse laden → … → EOICR schreiben → reentrant machen. Priorität 7–0 ordnet parallele IRQs.
- Polling vs. Interrupt Vor-/Nachteile (Kurzfrage).
- AIC vs. NVIC Unterschiede (Prioritäten, nested, automatisches Stacking, Tail-Chaining).
- Shared Data Problem + Lösung (critical section,
volatile). - IRQ vs. FIQ (FIQ schneller durch gebankte Register).
Typische Fehler: glauben, Interrupts müssten unterschiedliche Prioritäten haben (falsch - sie können gleiche haben) · EOICR vergessen · Busy Waiting mit Interrupt verwechseln (Busy Waiting reagiert schneller, aber blockiert).