共用方式為


使用 Passive-Level 中斷服務例程

從 Windows 8 開始,驅動程式可以使用 IoConnectInterruptEx 例程來註冊被動層級 的 InterruptService 例程 (ISR)。 當相關聯的中斷發生時,核心的中斷陷阱處理程式會排程此例程,在 IRQL = PASSIVE_LEVEL 執行。 如果ISR只能透過I/O要求存取裝置的硬體緩存器,可能需要在被動層級執行。 被動層級的 ISR 可以同步地向裝置傳送 I/O 請求,並在該請求完成前阻擋操作。

註冊 Passive-Level ISR

IoConnectInterruptEx 的輸入參數是IO_CONNECT_INTERRUPT_PARAMETERS結構的指標。 若要註冊被動層級 ISR,請將這個結構的 Version 成員設定為 CONNECT_FULLY_SPECIFIED 或 CONNECT_LINE_BASED。 如果 Version = CONNECT_FULLY_SPECIFIED,請將 Irql 成員設定為 PASSIVE_LEVEL、 將 SynchronizeIrql 成員設定為 PASSIVE_LEVEL,並將 SpinLock 成員設定為 NULL。 如果 Version = CONNECT_LINE_BASED,請設定 SynchronizeIrql = PASSIVE_LEVEL 和 SpinLock = NULL

如果中斷物件指定了被動層級的 ISR,那麼 KeSynchronizeExecution 例程會使用核心同步事件物件來同步 SynchCritSection 例程與 ISR 的執行,而不是使用旋轉鎖定。

這個事件物件是由註冊被動層級 ISR 之呼叫中的 IoConnectInterruptEx 例程所配置。 呼叫者不得在此呼叫中提供自旋鎖。 (也就是說,如果ISR是在被動層級執行,呼叫端必須將IO_CONNECT_INTERRUPT_PARAMETERS結構的SpinLock成員設定為NULL。否則,IoConnectInterruptEx 會失敗,並傳回錯誤狀態STATUS_INVALID_PARAMETER。

KeAcquireInterruptSpinLockKeReleaseInterruptSpinLock 例程如果在提供的中斷物件的 ISR 在 IRQL = PASSIVE_LEVEL 執行時,會導致錯誤檢查。

需要 Passive-Level 中斷處理的裝置

對於發出層級觸發中斷要求的記憶體對應裝置,裝置的ISR通常是從核心插斷陷阱處理程式內的 DIRQL 呼叫。 ISR 會操控裝置中的硬體寄存器,以關閉中斷。

不過,如果相關裝置發出層級觸發的中斷要求,而無法從在核心中斷陷阱處理程序中以 DIRQL 呼叫的 ISR 直接存取裝置的硬體暫存器,則 ISR 可能需要在 IRQL = PASSIVE_LEVEL 下執行。 例如,裝置暫存器可能不是記憶體對應,或ISR可能會在暫存器存取期間暫時被阻止。

從 Windows 8 開始,驅動程式可以註冊被動層級 ISR。 當中斷發生時,核心的中斷陷阱處理器會排程讓 ISR 在 IRQL = PASSIVE_LEVEL 執行。 在處理程序返回之前,它必須在中斷控制器(或 GPIO 控制器)中屏蔽中斷。 如果裝置發出邊緣觸發型中斷訊號,處理程式就會在中斷控制器內清除中斷。 如果裝置發出層級觸發的中斷訊號,處理程式會暫時屏蔽中斷控制器中的中斷;在ISR執行之後,核心會解除屏蔽中斷。

範例

可能需要被動層級ISR的裝置範例是連接到低功耗串列匯流排(如I²C)的感測器裝置。 從 Windows 8 開始,SPB 架構延伸模組 (SpbCx) 會提供 I}C 和其他簡單周邊總線的支援。

為了存取 I IoC 連接感測器裝置的快取器,感測器驅動程式會將感測器裝置傳送 I/O 要求,由 SpbCx 和總線控制器驅動程式共同處理。 若要執行要求的作業,SPB 控制器必須透過總線以序列方式傳輸數據。 此傳送速率相對較慢,而且無法在在 DIRQL 執行的 ISR 時間限制內執行。 不過,被動層級 ISR 可以同步傳送 I/O 要求,然後封鎖直到要求完成為止。

如果當ISR將I/O要求傳送至中斷裝置時關閉,本範例中的被動層級ISR可能會封鎖較長的時間。 在此情況下,控制器必須先完成轉換至 D0 電源狀態,才能透過總線傳輸數據。

相較於像PCI這樣的總線,本範例中的I²C總線不提供任何總線特定的方式來將周邊裝置的中斷請求傳遞給處理器。 相反地,感測器裝置可能會向 GPIO 控制器裝置上的引腳發出中斷訊號,然後將中斷要求轉送至處理器。 如需詳細資訊,請參閱 GPIO 中斷

一般而言,GPIO 控制器的硬體暫存器是記憶體對應的,可以由核心的中斷陷阱處理程式在 DIRQL 層級存取。 當感測器裝置造成中斷時,處理程式必須藉由作 GPIO 控制器緩存器中的插斷位來讓插斷無聲。

針對層級觸發的中斷,核心的插斷陷阱處理程式會遮罩 GPIO 針腳上的中斷要求,然後排程感測器裝置的 ISR 在被動層級執行。 ISR 必須清除感測器裝置的中斷要求。 ISR 傳回之後,核心會在 GPIO 針腳上解除遮罩中斷要求。

針對邊緣觸發的中斷,核心的陷阱處理程式會清除 GPIO 針腳上的中斷要求,然後排程感測器裝置的 ISR 在被動層級執行。

背景工作例程

在呼叫 IoConnectInterruptEx時,驅動程式可以選擇分割被動層級ISR與背景工作例程之間的中斷處理。 根據一般規則,ISR 應該執行中斷的初始處理(例如,抑制層級觸發的中斷),並將額外的處理交給工作處理程序。 雖然ISR和工作執行緒都以被動層級執行,但ISR會以相對較高的優先順序運行,而且可能會影響其他高優先順序的工作。 這些工作可能包括新中斷的被動層級ISR。

在罕見的情況下,中斷可能只需很少的處理,ISR被動層級可以執行所有中斷處理,且不需要任何工作例程。

如需在 KMDF 驅動程式中使用被動層級 ISR 的相關資訊,請參閱 支援 Passive-Level 中斷