ISR 작성
인터럽트 생성 물리적 디바이스용 드라이버에는 ISR(인터럽트 서비스 루틴)이 하나 이상 있어야 합니다. ISR은 디바이스의 인터럽트 중지를 포함하여 인터럽트 해제를 위해 디바이스에 적합한 모든 작업을 수행해야 합니다. 그런 다음, ISR이 실행되는 것보다 낮은 우선 순위(IRQL)로 I/O 작업을 완료하기 위해 상태를 저장하고 DPC를 큐에 대기하는 데 필요한 작업만 수행해야 합니다.
드라이버의 ISR은 SynchronizeIrql 매개 변수에서 IoConnectInterruptEx에 지정된 대로 일부 시스템 할당 DIRQL에서 인터럽트 컨텍스트에서 실행됩니다.
ISR은 인터럽트할 수 있습니다. 시스템 할당 DIRQL이 더 높은 다른 디바이스는 언제든지 인터럽트되거나 높은 IRQL 시스템 인터럽트일 수 있습니다.
시스템이 ISR을 호출하기 전에 ISR이 다른 프로세서에서 동시에 실행할 수 없도록 인터럽트의 스핀 잠금을 획득합니다. ISR이 반환되면 시스템은 스핀 잠금을 해제합니다.
ISR은 현재 프로세서에서 동등한 또는 낮은 IRQL로 인터럽트를 마스킹하는 비교적 높은 IRQL에서 실행되므로 가능한 한 빨리 제어를 반환해야 합니다. 또한 DIRQL에서 ISR을 실행하면 ISR이 호출할 수 있는 지원 루틴 집합이 제한됩니다. 자세한 내용은 하드웨어 우선 순위 관리를 참조하세요.
일반적으로 ISR은 다음과 같은 일반적인 단계를 수행합니다.
인터럽트 발생 디바이스가 ISR에서 지원되지 않는 경우 ISR은 즉시 FALSE를 반환합니다.
그렇지 않으면 ISR은 필요한 경우 인터럽트 지우고 필요한 디바이스 컨텍스트를 저장하고 DPC를 큐에 대기하여 낮은 IRQL에서 I/O 작업을 완료합니다. 자세한 내용은 DPC 개체 및 DPC 를 참조하세요. 그런 다음 ISR은 TRUE를 반환해야 합니다.
특히 디바이스 I/O 작업과 겹치지 않는 드라이버에서 ISR은 다음을 수행해야 합니다.
인터럽트 가 가짜인지 여부를 확인합니다. 그렇다면 중단된 디바이스의 ISR이 즉시 호출되도록 즉시 FALSE 를 반환합니다. 그렇지 않으면 인터럽트 처리를 계속합니다.
필요한 경우 디바이스의 중단을 중지합니다.
DpcForIsr(또는 CustomDpc) 루틴이 현재 작업에 대한 I/O 처리를 완료하는 데 필요한 컨텍스트 정보를 수집합니다.
DpcForIsr 또는 CustomDpc 루틴에 액세스할 수 있는 영역에 이 컨텍스트를 저장합니다. 일반적으로 현재 I/O 요청을 처리하여 인터럽트를 발생시킨 대상 디바이스 개체의 디바이스 확장에 저장합니다.
드라이버가 I/O 작업과 겹치는 경우 컨텍스트 정보에는 DPC 루틴이 완료하는 데 필요한 미해결 요청 수와 DPC 루틴이 각 요청을 완료하는 데 필요한 컨텍스트가 포함되어야 합니다. DPC가 실행되기 전에 다른 인터럽트를 처리하기 위해 ISR이 호출되면 DPC에서 아직 완료되지 않은 요청에 대해 저장된 컨텍스트를 덮어쓰지 않아야 합니다.
드라이버에 DpcForIsr 루틴이 있는 경우 현재 IRP, 대상 디바이스 개체 및 저장된 컨텍스트에 대한 포인터를 사용하여 IoRequestDpc 를 호출합니다. IoRequestDpc 는 IRQL이 프로세서의 DISPATCH_LEVEL 아래로 떨어지는 즉시 실행되도록 DpcForIsr 루틴을 큐에 대기합니다.
드라이버에 CustomDpc 루틴이 있는 경우 DPC 개체(CustomDpc 루틴과 연결됨)에 대한 포인터를 사용하여 KeInsertQueueDpc를 호출하고 CustomDpc 루틴이 작업을 완료하는 데 필요한 저장된 컨텍스트에 대한 포인터를 호출합니다. 일반적으로 ISR은 현재 IRP 및 대상 디바이스 개체에 대한 포인터도 전달합니다. CustomDpc 루틴은 IRQL이 프로세서에서 DISPATCH_LEVEL 밑으로 떨어지는 즉시 실행됩니다.
TRUE를 반환하여 디바이스가 인터럽트 생성을 나타냅니다.
일반적으로 ISR은 IRP를 충족하기 위해 실제 I/O 처리를 수행하지 않습니다. 대신 디바이스의 중단을 중지하고, 필요한 상태 정보를 설정하고, 드라이버의 DpcForIsr 또는 CustomDpc 를 큐에 대기하여 디바이스가 중단된 현재 요청을 충족하는 데 필요한 모든 I/O 처리를 수행합니다.
ISR은 가능한 가장 짧은 간격으로 DIRQL에서 실행되어야 합니다. 이 지침에 따라 DIRQL에서 실행하면 시스템에서 IRQL 값이 더 작거나 같은 할당된 모든 인터럽트가 차단되므로 컴퓨터의 모든 디바이스에 대한 I/O 처리량이 증가합니다.
드라이버가 IoConnectInterrupt라고 할 때 지정된 드라이버 인터럽트 개체의 SynchronizeIrql은 드라이버의 ISR이 실행되는 DIRQL을 결정합니다. 자세한 내용은 디바이스 데이터에 대한 액세스 동기화를 참조하세요.