Ich werde einige Code gründlich, die in etwa die folgenden tut:Interrupthandling in Gerätetreiber & Umfrage
- Kernel-Treiber verarbeitet eine Unterbrechung.
- Es gibt 1 Interrupt-Leitung. Wenn ein Interrupt auftritt, lesen die Handles ein 32-Bit-Register, das den Grund für diesen Interrupt angibt.
- Für jedes Bit, das festgelegt ist, ruft es ack_irq() auf, um den Interrupt zu löschen, und schreibt die Interruptursache in einen Puffer im Treiber für weiteres read().
- Als nächstes ruft es wake_up_interruptible() auf, um einen User-Space-Prozess zu aktivieren, der auf select() schläft.
- Die entsprechende poll() - Funktion führt poll_wait() durch.
- Sobald Auswahl zurückgibt, liest der User-Space() aus dem Treiber.
Während ich die grundlegende Bedienung von nur 1 Bit zu verstehen, was im folgenden Fall geschehen:
- Interrupt geschieht, und 1 Bit gesetzt ist.
- Handler ruft wake_up_interruptible() auf. poll() gibt zurück.
- Benutzerraum wacht auf, beginnen zu lesen().
- JETZT, ein weiterer Interrupt passiert -> Kernel behandelt den Interrupt und ruft wake_up_interruptible() auf, aber jetzt wartet niemand auf dieses Ereignis.
Bedeutet dies, dass der zweite Interrupt verpasst wird? Wenn ja, wie kann man das überwinden?
Angenommen, es ist ein Ringpuffer, und der Benutzerprozess liest, bis es nicht mehr zu lesen gibt (und eine ordnungsgemäße Sperre des Puffers vorausgesetzt), der Benutzerprozess wird nur die nächste Ursache aus dem Puffer lesen. –
Danke, es ist ein Ringspeicher, aber wir nehmen an, dass der Benutzerprozess die read() des ersten Interrupts beendet und kurz bevor er bei select() wieder in den Ruhezustand geht, ist der neue Interrupt angekommen. Der neue Interrupt wird wake_up_interruptible() aufrufen, aber der Benutzerprozess wartet noch nicht auf dieses Ereignis. – JZ500
"kurz bevor es wieder einschläft" wurde die neue "Ursache" in den Puffer gelegt, so dass select() den nächsten Wert zurückgibt. Der Aufruf wake_up_interruptible() tut einfach nichts (es gibt nichts aufzuwachen, weil nichts schläft). Rember es ist das Betriebssystem, das alles tut. Es greift die CPU bei dem Interrupt vom Benutzerprozess ab, so dass der Benutzerprozess nichts unternimmt, und gibt die CPU an den Benutzerprozess zurück, nachdem jede Reinigung durchgeführt wurde. Aus diesem Grund wird der Benutzerprozess nicht in den Ruhezustand versetzt. –